我正在使用JDK 1.4和1.5运行此代码并获得不同的结果。为什么会这样?
String str = "";
int test = 3;
str = String.valueOf(test);
System.out.println("str[" + str + "]\nequals result[" + (str == "3") + "]");
if (str == "3") {
System.out.println("if");
} else {
System.out.println("else");
}
输出:
on jdk 1.4
str[3]
equals result[true]
if
on jdk 1.5
str[3]
equals result[false]
else
答案 0 :(得分:11)
根据this page,Integer#toString
方法(由String#valueOf(int)
调用)在1.4中实现如下:
public static String toString(int i) {
switch(i) {
case Integer.MIN_VALUE: return "-2147483648";
case -3: return "-3";
case -2: return "-2";
case -1: return "-1";
case 0: return "0";
case 1: return "1";
case 2: return "2";
case 3: return "3";
case 4: return "4";
case 5: return "5";
case 6: return "6";
case 7: return "7";
case 8: return "8";
case 9: return "9";
case 10: return "10";
}
char[] buf = (char[])(perThreadBuffer.get());
int charPos = getChars(i, buf);
return new String(buf, charPos, 12 - charPos);
}
这可以解释您的结果,因为字符串文字"3"
是实习的,"3" == "3"
总是返回true。
您可以尝试使用10和11进行验证。
注意:如前所述,Integer#toString
的javadoc没有说明返回的字符串是否会被实习,因此问题中的两个输出都同样有效。
答案 1 :(得分:4)
这是JLS未指定的实现细节。
引用相等运算符==
检查两个变量是否指向同一个实际对象,而equals
方法检查两个变量的值是否以某种方式“相等”由程序员决定。在这种情况下,1.4 JVM似乎利用String
在调用"3"
和1.5 JVM时重用字符串valueOf
的相同副本是不可变的这一事实不是。这两种选择都是完全合法的,你不应该依赖任何特定的行为。
答案 2 :(得分:1)
从java 5开始,string.valueof()应该返回新的字符串。而不是实习(编辑)(共享)字符串!
考虑以下示例
int test = 3;
String str = String.valueOf(test);
String str2 = String.valueOf(test);
if(str == str2)
System.out.println("valueOf return interned string");
else
System.out.println("valueOf does not return interned string");
java>中的输出= 5
valueOf does not return interned string
但是在java 4中输出是
valueOf return interned string
这解释了这种行为!
答案 3 :(得分:0)
如果在字符串文字的操作上使用“==”运算符,则它取决于字符串文字值是否存在于“字符串池”中,在您的情况下变量“str”是字符串JVM优先检查“字符串池”,如果找到,则返回TRUE,否则返回FALSE。使用intern()方法尝试以下代码,以使字符串文字可用于“字符串池”
String str = "";
int test = 3;
str = String.valueOf(test).intern();
System.out.println("str[" + str + "]\nequals result[" + (str == "3") + "]");
if (str == "3") {
System.out.println("if");
} else {
System.out.println("else");
}
根据intern()方法的文档: intern()方法在字符串的内部表中搜索等于此String的字符串。如果字符串不在表中,则添加它。回答表中包含的字符串,该字符串等于此String。对于相同的字符串,总是会回答相同的字符串对象。
不建议将“==”操作用于字符串比较。使用equals()或equalsIgnoreCase()方法()。
我甚至在java 1.7 中没有 intern()尝试输出
str[3]
equals result[false]
else
与 intern()输出结果为:
str[3]
equals result[true]
if
这不是jdk 1.4和1.5的问题,这是一个“逻辑错误”。