- 谈谈你对java平台的理解?java是解释执行,这句话正确吗?
答:java本身是一种面向对象的语言,最显著特性是2个方面,1是书写一次,到处运行即跨平台,另外1个是垃圾回收,java通过垃圾收集器回收分配的内存,大部分情况下,程序员不需要自己操作内存的分配和回收。
对于java是解释执行这句话,说法不太正确,我们开发的java源码即.java文件,首先通过javac编译器编译为字节码,然后运行时,通过jvm内嵌的解释器将字节码转换为最终的机器码,但常见jvm,eg:oracle jdk提供的Hotspot jvm,都提供了JIT(Just-in-time)编译器即动态编译器。JIT能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而非解释执行。
- JDK 和 JRE 有什么区别?
JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境。
JRE:Java Runtime Environment 的简称,java 运行环境,为 java 的运行提供了所需环境。
具体来说 JDK 其实包含了 JRE,同时还包含了编译 java 源码的编译器 javac,还包含了很多 java 程序调试和分析的工具。简单来说:如果你需要运行 java 程序,只需安装 JRE 就可以了,如果你需要编写 java 程序,需要安装 JDK。
- == 和 equals 的区别是什么?
答:==是java的运算符,对于基本类型、引用类型效果不同
基本类型:比较的是值是否相同;注意一下包装类
引用类型:比较的是引用是否相同;
而equals是java所有类的方法(因为超级父类Object就有此方法)
public boolean equals(Object obj) { return (this == obj);}
java有不成文的规定重写equals必须重写hashCode方法,必须保证equal是相等,hashCode必须相等。Equals一般认为是比较值相等
String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x==y); // true
System.out.println(x==z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true
代码解读:因为 x 和 y 指向的是同一个引用,所以 == 也是 true,而 new String()方法则重写开辟了内存空间,所以 == 结果为 false,而 equals 比较的一直是值,所以结果都为 true
总结 :== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。
- 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
答:不对,两个对象的 hashCode()相同,equals()不一定 true
String str1 = "通话"; String str2 = "重地";
System.out.println(String.format("str1:%d | str2:%d", str1.hashCode(),str2.hashCode()));
System.out.println(str1.equals(str2));
- final在java中的作用?
final修饰类表示此类不能被继承
final修饰方法表示此方法不能被重写
final修饰变量表示此变量不能变(基本变量值不变,引用变量地址不变,内容可变)并且成员变量声明时必须赋值或在构造器中赋值。修饰方法的形参避免赋值。
final也有性能的好处,有助于jvm将方法进行内联&指令重排等
final在高并发的好处,因为明确不能再赋值,有利于减少额外的同步开销,也可省去一些防御性拷贝的必要。
final修饰变量
归纳总结:
-
类变量:必须要在静态初始化块中指定初始值或者声明该类变量时指定初始值,而且只能在这两个地方之一进行指定;
-
实例变量:必要要在非静态初始化块,声明该实例变量或者在构造器中指定初始值,而且只能在这三个地方进行指定
public void testA(final String name){ System.out.println(name); // 不能赋值 // name="xinxin"; final int d; // 没有默认值 // System.out.println(d); d=10; System.out.println(d); }
- final、finally、finalize的区别?
答:就是长的有点像,final已经讲了
finally和final都是关键字,是用于关闭资源的,try-catch-finally或try-finally。我推荐使用java 7try-with-resources。finally有一个特例,让它不会执行
try{
System.exit(1);
}finally{
Sout(“我没有被执行”);
}
finalize是Object的方法,不推荐使用,java9已经标识废弃,无法保证什么时候执行,执行是否符合预期,使用不当会影响性能,导致程序死锁、挂起等。所以资源用完即显示是否或利用资源池来尽量重用。
- 什么是不可变类?
不可变类的意思是创建该类的实例后,该实例的属性是不可改变的;所以不可变类并不是指该类是被final修饰的,而是指该类的属性是被final修饰的
自定义不可变类遵守如下原则:
1> 使用private和final修饰符来修饰该类的属性。
2> 提供带参数的构造器,用于根据传入的参数来初始化属性。
3> 仅为该类属性提供getter方法,不要提供setter方法。并且使用copy-on-write原则,创建私有的copy
4> 如果有必要,重写hashCode和equals方法,同时应保证两个用equals方法判断为相等的对象,其hashCode也应相等
5> 通常构造对象时,成员变量使用深度拷贝来初始化,而不是直接赋值,这是一种防御措施,因为你无法确定输入变量不被其他人修改
Ps:
List<String> immutableList = List.of(“不可变的list”); immutableList.add(“allen”);会抛异常