1、intern()方法
“ab”.intern():这个方法会首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然后返回这个常量池中字符串的引用。以下代码是在jdk1.8中测试,jdk1.6会有所不同。
public static void main(String[] args) {
// 创建2个对象,一个String对象在堆中,一个String常量在常量池
String s = new String("2");
// 判断s是否在常量池中,存在则返回常量池中对象的引用,此时intern指向常量池中的对象
String intern = s.intern();
// s2字符串在常量池中,所以返回常量池中的对象引用
String s2 = "2";
// s:为堆中对象 s2:为常量池对象 所以:false
System.out.println(s == s2); // false
// intern和s2都是指向常量池中的字符串,所以:true
System.out.println(intern == s2); // true
System.out.println("------------------------");
// 创建4个对象:堆中"33","3","3"对象,常量池:"3"对象
String s3 = new String("3") + new String("3");
// 判断s3是否在常量池中,不存在则将s3加入常量池中,并且常量池中保存的是s3的引用,返回常量池中对象的引用,此时s3和intern2指向同一个对象
String intern2 = s3.intern();
// s4字符串在常量池中,所以返回常量池中的对象引用
String s4 = "33";
// s3和intern2和s4指向的是同一个对象
System.out.println(s3 == s4); // true
System.out.println(intern2 == s3); // true
System.out.println(intern2 == s4); // true
}
2、try…catch…finally
// 返回 40
public static int fun(){
int a = 10;
try{
System.out.println(a / 0);
a = 20;
// return a;
}catch (Exception e){
a = 30;
return a;
}finally {
a = 40;
return a;
}
}
// 返回 30
public static int fun(){
int a = 10;
try{
System.out.println(a / 0);
a = 20;
// return a;
}catch (Exception e){
a = 30;
return a;
}finally {
a = 40;
}
return a;
}
// 返回 30
public static int fun(){
int a = 10;
try{
System.out.println(a / 0);
a = 20;
return a;
}catch (Exception e){
a = 30;
return a;
}finally {
a = 40;
}
}
3、hashCode和equals的关系
- equals相等的两个对象,hashCode一定相等
- hashCode相等的两个对象,equals不一定相等
使用Object.hashCode,是根据随机算法生成的hashCode值,无法保证两个对象equals相等的时候,hashCode也相等。
像一些集合容器map,在进行比较两个对象相等的判定条件是hashcode和equals都相等,所有在重写equals时,必须要重写hashCode,才能保证集合容器的正确使用。
4、什么是反射,反射有什么缺点?
反射是指在程序运行时动态获取类的信息、调用类的方法、访问类的属性等操作能力。在Java中,反射允许程序在运行时检查和操作类、方法、字段等,使得程序可以在运行时动态地创建对象、调用方法、修改属性等。
反射的缺点包括:
- 性能问题:由于反射涉及到动态查找和调用,相比直接调用方法,反射的性能会有一定的损耗。反射操作通常比直接操作更慢,因此在性能要求较高的场景下,应该谨慎使用反射。
- 安全问题:反射可以访问和修改类的私有方法和属性,可能会破坏类的封装性,导致安全隐患。使用反射时需要格外小心,确保不会对程序的安全性造成影响。
- 可读性和维护性差:由于反射是在运行时动态获取类信息,代码的可读性和维护性可能会受到影响。反射使得代码结构不够清晰,增加了代码的复杂性,降低了代码的可读性和维护性。
- 编译器检查失效:使用反射可以绕过编译器的类型检查,可能导致运行时的类型错误,增加了程序出错的可能性。因此,在使用反射时需要格外小心,确保类型安全。
- 不利于性能优化:由于反射的灵活性和动态性,使得程序的结构和行为不够明确,不利于编译器进行优化,可能影响程序的性能表现。