1 为什么Java被称作是与平台无关的编程语言
java跨平台是指在不同的平台安装不同的JVM,字节码文件由JVM解释成对应平台的机器码。
2 理解JDK,JRE,JVM
- JDK:Java开发工具包,包括JRE,还有一些小工具如javac.exe
- JRE:Java运行环境,JVM实现(jre/bin/server/jvm.dll)+java基本类库(rt.jar等)
- JVM:Java虚拟机,执行.class文件,是Java支持跨平台的关键
3 JDK各个版本的新特性
-
JDK5 自动装箱拆箱 增强for循环 静态导入 可变参数 枚举 线程并发库JUC 注解
-
JDK7
- 二进制字面值,int a=0b1001
- switch支持String类型,反编译可以看到其原理是 - 根据str的hashcode来匹配,如果为null会报空指针异常
- try-with-resources
- catch 多个类型异常
- 字面值中使用下划线
- 类型推断
-
JDK8
- lambda表达式
- 函数接口
- StreamAPI
- 新的日期时间API:LocalDate、LocalTime 和 LocalDateTime类
- optional类
- 增强类型推断
- 方法引用等,如类::实例方法
- 接口支持默认方法,静态方法
-
JDK9
- 目录结构:JDK目录结构有变化,其中去掉了jre目录
- 模块化系统
- 接口的私有方法
- 改进try-with-resources
- String存储结构变化,由char[]变为byte[]
参考www.cnblogs.com/peter1018/p…
4 int和Integer
int和Integer的区别
- 数据类型不一样,int是基础数据类型,Integer是包装数据类型
- 默认值不一样,int初始值是0,Integer初始值是null
- 存储方式不一样,int存储在栈中,Integer存储在堆中
- Integer是对象类型,封装了很多方法,使用更灵活
- 泛型只能使用Integer
int和Integer使用场景
- 整数运算使用int,加减乘除运管比较多
- 高精度运算使用Integer
- 集合元素用Integer
- 泛型使用int
5 java中四种修饰符的限制范围
- public所有类
- default包
- protect子类
- private本类
6 接口和抽象类的区别,注意JDK8的接口可以有实现。
- 接口支持多实现,抽象类只能单继承
- 实现接口时,必须实现所有方法,继承抽象类,不需要实现所有方法,可以定义成抽象的
- 接口中的实例变量默认是static final
7 值传递和引用传递的区别。
- 值传递,传递的是值的副本,不会影响原值,基本类型是值传递
- 引用传递,传递的是对象的引用,两个引用指向的是同一个对象,改变引用的实体将改变原实体的值,引用类型都是引用传递
8 为什么重写equals方法时必须重写hashcode方法
object规范的约定内容如下:
两个对象根据equals方法比较相等,其hashcode必须相等。 两个对象不相等,其hashcode不要求一定不相同,但我们应该知道,给不同的对象生成截然不同的hashcode值,有可能提供哈希表的效率。
9 泛型
泛型在编译时强化元素类型信息,并在运行时擦除。有了泛型之后,编译时就可以知道是否插入了类型错误的对象。
List为原生类型,原生类型的存在是为了兼容Java5之前的代码,是不安全的,在Java5之后尽量使用泛型 List<Object>表示可以包含任何对象类型的集合 List<?>表示只能包含某种未知对象类型的集合,为无限制通配类型
举例说明List、List<Object>和List<?>的区别
- List可以接收List类型的参数,运行时可能报错,使用原生类型失去了类型安全性
- List不能接收List类型的参数,编译时报错
- List不能将任何元素(除了null)放到List中,编译时报错
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
addofPrototypeList(list, new Integer(10));
String str = list.get(0);//运行时报类型转换错误
addofObjectList(list, new Integer(10));//编译时报错
add(list, new Integer(10));
}
private static void addofPrototypeList(List list, Object o) {
list.add(o);
}
private static void addofObjectList(List<Object> list, Object o) {
list.add(o);
}
private static void add(List<?> list, Object o) {
list.add(o);//编译时报错
}
10 static
- 静态变量被所有的对象所共享,在类初次加载时会被初始化,在内存中只有一个副本,。
- 非静态变量在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
11 this逃逸
- 含义:对象没有构造完成,对象的this引用就被发布出去了。
- 产生条件:在构造函数中创建并发布了内部类。
- 举例:在一个类的构造器创建了一个内部类(内部类拥有对外部类所有成员的访问权),此时外部类的成员变量还没初始化完成,但内部类被其他线程获取到,并调用了内部类访问到外部类未初始化的成员变量的方法。
- www.cnblogs.com/straybirds/…
12 代码加载顺序
父类
public class Father {
public Father(){
System.out.println("4 父类静态构造函数");
}
{
System.out.println("3 父类静态构造代码块");
}
static{
System.out.println("1 父类静态代码块");
}
}
子类
public class Son extends Father{
public Son(){
System.out.println("6 子类静态构造函数");
}
{
System.out.println("5 子类静态构造代码块");
}
static{
System.out.println("2 子类静态代码块");
}
public static void main(String[] args) {
System.out.println("main 开始...");
new Son();
new Son();
System.out.println("main 结束");
}
}
输出结果
1 父类静态代码块
2 子类静态代码块
main 开始...
3 父类静态构造代码块
4 父类静态构造函数
5 子类静态构造代码块
6 子类静态构造函数
3 父类静态构造代码块
4 父类静态构造函数
5 子类静态构造代码块
6 子类静态构造函数
main 结束
总结
- 在主类中定义的静态块,优先于主方法(main)执行
- 静态块优先于构造块执行。无论产生多少实例化对象,静态块都只执行一次。
- 构造块优先于构造方法执行,每产生一个新的对象就调用一次构造块,构造块可以进行简单的逻辑操作
- 有继承关系的话,在main方法里 new 子类,则先调父类,再调子类
13 finally和return执行问题
- 不管有没有出现异常,finally块中代码都会执行;
- 当try和catch中有return时,finally仍然会执行;如下:
try{
return;
}catch(){
}finally{
}
return;
-
程序执行try块中return之前(包括return语句中的表达式运算)代码; 再执行finally块,最后执行try中return; finally块之后的语句return,因为程序在try中已经return所以不再执行。
-
finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来, 不管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
-
finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
14 内部类
- 成员内部类 成员内部类,可以访问外部类的所有成员 内部类不允许定义静态变量
- 局部内部类(方法内定义) 可以访问当前代码块内的常量,和此外围类所有的成员。 局部内部类访问它所在方法的局部变量时,要求该局部变量必须声明为final的原因 (原因:局部内部类对象的生命周期比局部变量的生命周期长) 局部内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。
- 静态内部类 要创建内部类的对象,并不需要其外部类的对象。 不能访问外部类的非静态对象。
- 匿名内部类 www.cnblogs.com/ldl326308/p…
15 深拷贝、浅拷贝
- 深拷贝:目标对象和原对象是独立的,不会互相影响
- 浅拷贝:
- 值类型:拷贝对象的值
- 引用类型,拷贝对象的地址,修改目标对象会改变原对象的值
16 异常类
- Throwable:Error和Exception(包括-RuntimeException)
- 可查异常:Exception中除RuntimeException的异常,必需处理,捕获或抛出
- 不可查异常:Error和RuntimeException,可以处理也可以不处理
- 运行时异常:runtimeException
17 创建对象的方法
- 用new语句创建对象
- 运用反射手段,调用java.lang.Class 或者 java.lang.reflect.Constructor 类的newInstance()实例方法
- 调用对象的clone()方法
- 运用序列化手段,调用java.io.ObjectInputStream 对象的 readObject()方法(对象的反序列化,对象输入流)