public static void main(String[] args){
one();
two();
three();
}
public static void one() {
String s1 = "hill5";
String s2 = "hill" + 5;
System.out.println(s1==s2);
}
public static void two() {
String s1 = "hill5";
int i =5;
String s2 = "hill" + i;
System.out.println(s1==s2);
}
public static void three() {
String s1 = "hill5";
String s2 = "hill" + s1.length();
System.out.println(s1==s2);
}
输出
true
false
false
字符串文字使用实习过程,然后two()
和three()
为假。我可以理解three()
但two()
不清楚。但需要正确解释对于这两种情况。
有人可以解释正确的理由吗?
答案 0 :(得分:14)
对于2和3,编译器无法计算String的值,因为hill + i
是运行时语句,s1.length()
在这里阅读我问同样的案例 - link
这样认为String s1 and s2
正在使用编译时常量s1="hill5"
和s2="hill" + 5
,请记住,作为文字指定的字符串是常量,其状态不能被修改,因为字符串是不可变的。
所以在编译时,编译器说“哦是的,它们被计算为相同的值,我必须为s1和s2分配相同的引用”。
但是在方法two()
和three()
的情况下,编译器说“我不知道,可能随时都可以更改i的值,或者s1.length()
随时更改”,运行时事件,因此编译器不会将two()
和three()
方法的s2放在池中,
因此,它们是错误的,因为在运行时,一旦它被改变了就会创建新对象!!
答案 1 :(得分:0)
带有编译时间常量表达式的字符串将被放在字符串池中。主要条件是编译时间常数表达式。如果您在方法two()
中使局部变量为final,则two()
还将打印true
public static void two() {
String s1 = "hill5";
final int i =5;
String s2 = "hill" + i;
System.out.println(s1==s2);
}
输出:
true