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


我正在使用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");
}

输出:

  • 在jdk 1.4

    str[3]
    equals result[true]
    if
    
  • 在jdk 1.5

    str[3]
    equals result[false]
    else
    

4819
2017-08-01 04:46


起源

检查字符串相等性 "3".equals(str) 而不是 == 运营商。 - Narendra Pathai
这与JDK之间的差异无关,而是你对如何理解 String 比较适用于Java。查看我之前评论中提供的链接 - MadProgrammer
比较你必须使用的java中的对象相等性 equals ,使用==如果他们引用同一个对象......如果他们被实习,那么你就是真的。 - nachokk
@NarendraPathai我认为问题是为什么输出与jdk 1.4和1.5不同。 - assylias
@assylias这与1.4和1.5中不同的字符串行为的实习有关。你有什么需要? - Narendra Pathai


答案:


根据 这一页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来验证这一点。

注意:如前所述,javadoc Integer#toString 没有说明返回的字符串是否会被实习,因此您的问题中的两个输出都同样有效。


11
2017-08-01 05:30



+1在Java 7中再次不同。你不应该依赖这样的行为。 - Peter Lawrey


这是JLS未指定的实现细节。

引用相等运算符 == 检查两个变量是否指向同一个实际对象,而 equals 方法检查两个变量的值是否以某种方式“相等”,这可能由程序员确定。在这种情况下,似乎1.4 JVM正在利用这一事实 Strings是不可变的,可以重用相同的字符串副本 "3" 你打电话时 valueOf 并且1.5 JVM不是。这两个选项都是完全合法的,您不应该依赖任何特定的此类行为。


4
2017-08-01 05:18





从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

这解释了这种行为!


1
2017-08-01 06:25



你正在重述操作已经观察到的内容。问题是:为什么1.4和1.5表现不同。 - assylias
因为在java 5中创建了新的字符串而不是实习(ed)(共享)字符串。看第1个粗线! - Aniket Thakur


如果你在字符串文字的操作上使用“==”运算符,那么它取决于字符串文字值是否存在于“字符串池”中,在你的情况下变量“str”是一个字符串JVM首先检查“ String Pool“如果找到则返回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的问题,这是一个“逻辑错误”。


0
2017-08-01 05:44