为什么JDK 1.4和1.5之间的输出不同?

时间:2013-08-01 04:46:41

标签: java jdk1.5 jdk1.4

我正在使用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
    

4 个答案:

答案 0 :(得分:11)

根据this pageInteger#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的问题,这是一个“逻辑错误”。