java - jdk7和jdk8的String有什么区别?

标签 java jvm

我这里有下面的代码,我想知道为什么相同的代码在jdk7和jdk8中产生不同的结果?

String s3 = new String("1") + new String("1");
System.out.println(System.identityHashCode(s3));    //JDK7 1485288136 - JDK8 985655350
String s3i = s3.intern();
System.out.println(System.identityHashCode(s3i));   //JDK7 1485288136 - JDK8 804611486
System.out.println(System.identityHashCode(s3));    //JDK7 1485288136 - JDK8 985655350
String s4 = "11";
System.out.println(System.identityHashCode(s4));    //JDK7 1485288136 - JDK8 804611486
System.out.println(s3 == s4); // JDK7 true - JDK8 false

正确

似乎不只是因为 JDK,关于 junit。

import org.junit.Test;

public class StringDemo {

    @Test
    public void test() {
        String s3 = new String("1") + new String("1");
        s3.intern();
        String s4 = "11";
        System.out.println(s3 == s4);
        // JDK7 true - JDK8 false
    }

    public static void main(String[] args) {
        String s3 = new String("1") + new String("1");
        s3.intern();
        String s4 = "11";
        System.out.println(s3 == s4);
        // JDK7 true - JDK8 true
    }

}

最佳答案

您正在深入研究 identityHashCode() 和字符串实习的实现细节,这些细节在不同版本之间可能存在差异,并且确实存在差异。这种行为本质上是未定义的。

FWIW,我的 Java 8 输出如下:

1829164700
1829164700
1829164700
1829164700
true

...但这当然不能保证:

  • identityHashCode() 可以在 任何 内部对象状态不同或算法不同时不同 - 这些都可以在版本之间更改。除了等于(或不等于)以相同方式生成的另一个值之外,该值本身没有任何意义。 这就是散列码在不同版本之间不相同的原因。
  • intern() 在不同版本甚至调用中的行为可能不完全相同(正如您在 junit 示例中看到的那样)。具体来说,它可能不会返回相同的字符串您传入的对象 - 它所保证的是:

    (returns) a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.

    这就是为什么 s3==s4 可能为真也可能不为真,同样为什么比较 s3s4 可能不同也可能不同。

关于java - jdk7和jdk8的String有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57308346/

相关文章:

Java "Virtual Machine"与 Python "Interpreter"的说法?

java - 如何处理各种电子邮件提供商的传递状态通知?

java - 在嵌套对象上使用 lambda 和流

java-8 - 如何将安全点日志输出到指定文件中?

java - Java 代码是保存在本地编译的类数据共享存档 (classes.jsa) 中还是字节码?

java - 如何在 Java 进程 Hits OutOfMemory Error 时自动创建 Heap Dump?

java - AbstractProcessor,如何声明哪个目标是另一个注释的注释?

java - 如何读取InputStream中间的偏移量?

java - 使用Java向mysql插入值时,为什么得到null空varchar记录和0作为日期记录?

java - 增加 maxpermsize 和最大堆大小的副作用