12
String h = "hi";

在这里,我们将字符串 h 引用到字符串文字 hi。JVM 有一个字符串文字池来存储字符串文字,因此我们可以重用字符串,因为它们是不可变的......

当我们说reusable,这个的确切含义是什么?我们在谈论address吗?每次都是从同一个地址挑选出来的吗?

4

4 回答 4

12

是的,为了使事情更简单,您可以将其视为从同一地址进行选择,但更准确地说,变量持有相同的引用,即 JVM 在映射到对象的正确内存地址时使用的数字/对象 ID 对象可以在内存中移动但仍会有相同的参考)。

您可以使用如下代码对其进行测试:

String w1 = "word";
String w2 = "word";
String b = new String("word"); // explicitly created String (by `new` operator) 
                               // won't be placed in string pool automatically
System.out.println(w1 == w2);  // true  -> variables hold same reference
System.out.println(w1 == b);   // false -> variable hold different references,
                               // so they represent different objects
b = b.intern(); // checks if pool contains this string, if not puts this string in pool, 
                // then returns reference of string from pool and stores it in `b` variable
System.out.println(w1 == b);   // true  -> now b holds same reference as w1
于 2012-05-25T19:05:59.517 回答
9

如果是

String h = "hi";
String i = "hi";
String j = new String("hi");

根据 JDK 的版本,编译器可能会执行所谓的实习,并创建表示 的字节数据的单个实例,"hi"并在 to 变量引用之间重用它。在最新的规范中,所有字符串文字都被嵌入到永久代的字符串池中。

在最后一条语句中使用new关键字将创建一个与单独对象完全相同的字节的新实例。

在运行时创建的字符串对象不在字符串池中,除非.intern()对其调用。这通常是不需要的,并且可能会导致问题,很少有任何显着的好处。

h == i; // true
h == j; // false
j.intern();
h == j; // true
于 2012-05-25T18:49:53.990 回答
5

这意味着如果 20 个对象使用相同的文字字符串:

private String h = "hi";

所有这些对象实际上都会引用内存中的同一个 String 实例。没关系,因为它是不可变的,所以不可能改变 String 的内容。因此,相同的实例可以在对象之间毫无问题地共享。

于 2012-05-25T18:49:58.563 回答
4

JVM 内部有一个String文字池,其中包含String在程序生命周期内创建的所有 s。可重用意味着,当您想使用String具有完全相同字符和编码的另一个对象时String,不会创建新对象。相反,该引用将指向String字符串池中已经存在的。这称为实习。

可以这样做是因为Strings 在 Java 中是不可变的。

这样做的原因是为了避免创建新String对象的成本。

在此处查看有关字符串文字池是什么以及它如何工作的更多详细信息:http ://www.xyzws.com/Javafaq/what-is-string-literal-pool/3

另外,看看这个问题:我不应该在 Java 中执行 `String s = new String("a new string");`,即使使用自动字符串实习?

于 2012-05-25T18:50:24.343 回答