一些常见的面试题:
String a = "hello2";
String b = "hello" + 2;
System.out.println(a == b);
a == b输出true。很明显b在编译时就被优化成“hello2”,因此在运行期间,a和b指向的是统一对象
String a = "hello2";
String b = "hello";
String c = b + 2;
System.out.println(a == c);
a==c输出false,因为b是变量,不会在编译期间被优化,不会把 b + 2当成字符常量来处理的。这种情况生成的对象实际上保存在堆上。
String a = "hello2";
final String b = "hello";
String c = b + 2;
System.out.println(a == c);
输出:true。被final修饰的变量,会在class文件常量池中保存一个副本。那么b + 2在编译期间会被优化成”hello” + 2。也可以把final修饰的变量看做常量。
public class Main {
public static void main(String[] args) {
String a = "hello2";
final String b = getHello();
String c = b + 2;
System.out.println((a == c));
}
public static String getHello() {
return "hello";
}
}
输出:false。因为b虽然是final变量,但是由于其赋值只能在运行期间确定。
public class Main {
public static void main(String[] args) {
String a = "hello";
String b = new String("hello");
String c = new String("hello");
String d = b.intern();
System.out.println(a==b);
System.out.println(b==c);
System.out.println(b==d);
System.out.println(a==d);
}
}
输出:false,false,false,true
intern方法是一个本地方法,会在运行时常量池中查找是否存在内容相同的字符串,如果有则返回该对象的引用;如果没有,则将该字符串入池,并且返回该对象的引用,所以是true。