62,614
社区成员
发帖
与我相关
我的任务
分享
public class test3 {
public static void main(String[] args) {
String a = "hello2";
final String b = "hello";
String d = "hello";
String c = b + 2;
String e = d + 2;
System.out.println(c);
System.out.println(e);
System.out.println((a == c));
System.out.println((a == e));
System.out.println(a.equals(c));
System.out.println(a.equals(e));
}
}
public class Test {
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";
}
}
public class T {
public static void main(String[] args) {
String a = "hello";
String a1 = "hello";
String d = a+2;
String d1 = a1+2;
System.out.println((d == d1));
}
}
结果是:false
这个结果说明,d和d1是值相同,但引用地址不同的两个对象。求帮忙解释下原因
String a = "hello2";
final String b = "hello";
String d = "hello";
String c = b + 2;
String e = d + 2;
怎么解释a == c,结果为true。
对于a来说,hello2保存在堆内存中,在栈中分配一个地址 地址a-->hello2
分配对于c来说,b是一个常量,开始是保存在常量池中的,当执行b+2时,
才会把b+2当成一个新的字符串hello2取出来,然后读取内存发现已经存在了
hello2,所以不再创建,直接把c指向a在内存中的地址,因此a == c;
对于d,内存中原来是不存在hello的,所以执行到d的时候就会在内存中新开辟一个地址
用于保存hello,这样执行d+2的时候,e指向的地址不是a,所以e != a
////问题1
String a = "hello2";
final String b = "hello";
String d = "hello";
///问题2
String c = b + 2;
[/quote]
好吧 我说呢,怎么分析半天得出个错误的结果
////问题1
String a = "hello2";
final String b = "hello";
String d = "hello";
///问题2
String c = b + 2;
String a = "hello2";
final String b = "hello";
String d = "hello";
String c = b + 2;
这里b被你声明成了final的了,所以就是常量,常量表达式String c = b + 2;,JVM会优化成String c = "hello" + 2;,这个结果是变成编译期就是已知了,指向常量池中的hello2字符串,也就是a。
第二个问题:明白了第一个问题,你就应该自己知道了,因为这里的b虽然是常量,但是在编译期是不能获得值的,只有在运行的时候才会调用函数,初始化赋值,所以这时的String c = b+2是运行期间计算出来的,而加号连接运算符,内部则是调用的StringBuilder,然后toString,所以c相当于是new出来的String,即c是指向堆内存的地址,c内部的char数组才指向常量池中的字符串,所以明显a != c