简体   繁体   English

Java字符串实习,有什么保证?

[英]Java string interning, what is guaranteed?

The question boils down to this code: 问题归结为这段代码:

// setup
String str1 = "some string";
String str2 = new String(str1);
assert str1.equals(str2);
assert str1 != str2;
String str3 = str2.intern();

// question cases
boolean case1 = str1 == "some string";
boolean case2 = str1 == str3;

Does Java standard give any guarantees about values of case1 and case2 ? 难道Java标准提供有关的价值观任何保证 case1case2 Link to relevant part of Java spec would be nice, of course. 当然,链接到Java规范的相关部分会很好。

Yes, I looked at all the "Similar Questions" found by SO, and found no duplicates, as none I found answered the question this way. 是的,我查看了SO发现的所有“类似问题”,发现没有重复,因为没有我发现这样回答了问题。 And no, this is not about the misguided idea of "optimizing" string comparisons by replacing equals with == . 不,这不是关于通过用==替换equals “优化”字符串比较的错误想法。

Here is your JLS quote, Section 3.10.5 : 这是您的JLS报价, 第3.10.5节

Each string literal is a reference (§4.3) to an instance (§4.3.1, §12.5) of class String (§4.3.3). 每个字符串文字都是类String(第4.3.3节)的实例(第4.3.1节,第12.5节)的引用(第4.3节)。 String objects have a constant value. String对象具有常量值。 String literals-or, more generally, strings that are the values of constant expressions (§15.28)-are "interned" so as to share unique instances, using the method String.intern. 字符串文字 - 或者更一般地说,作为常量表达式(第15.28节)的值的字符串 - 是“实例化”以便使用String.intern方法共享唯一实例。

Thus, the test program consisting of the compilation unit (§7.3): 因此,测试程序由编译单元组成(第7.3节):

package testPackage;
class Test {
        public static void main(String[] args) {
                String hello = "Hello", lo = "lo";
                System.out.print((hello == "Hello") + " ");
                System.out.print((Other.hello == hello) + " ");
                System.out.print((other.Other.hello == hello) + " ");
                System.out.print((hello == ("Hel"+"lo")) + " ");
                System.out.print((hello == ("Hel"+lo)) + " ");
                System.out.println(hello == ("Hel"+lo).intern());
        }
}

class Other { static String hello = "Hello"; }

and the compilation unit: 和编译单位:

package other;

public class Other { static String hello = "Hello"; }

produces the output: true true true true false true 产生输出:true true true true false

This example illustrates six points: 这个例子说明了六点:

Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1). 同一个包(第7节)中同一个类(第8节)中的文字字符串表示对同一个String对象的引用(第4.3.1节)。

Literal strings within different classes in the same package represent references to the same String object. 同一个包中不同类中的文字字符串表示对同一String对象的引用。

Literal strings within different classes in different packages likewise represent references to the same String object. 不同包中不同类中的文字字符串同样表示对同一String对象的引用。

Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals. 由常量表达式计算的字符串(第15.28节)在编译时计算,然后将其视为文字。

Strings computed by concatenation at run time are newly created and therefore distinct. 在运行时通过串联计算的字符串是新创建的,因此是不同的。 The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents. 显式实现计算字符串的结果与具有相同内容的任何预先存在的文字字符串的字符串相同。

Combined with the JavaDoc for intern, and you have enough information to deduce that both of your cases will return true. 结合实习的JavaDoc ,您有足够的信息来推断您的两个案例都将返回true。

I think String.intern API provides enough information 我认为String.intern API提供了足够的信息

A pool of strings, initially empty, is maintained privately by the class String. 最初为空的字符串池由String类私有维护。

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. 调用实习方法时,如果池已经包含等于此字符串对象的字符串(由equals(Object)方法确定),则返回池中的字符串。 Otherwise, this String object is added to the pool and a reference to this String object is returned. 否则,将此String对象添加到池中,并返回对此String对象的引用。

It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true. 因此,对于任何两个字符串s和t,当且仅当s.equals(t)为真时,s.intern()== t.intern()才为真。

All literal strings and string-valued constant expressions are interned. 所有文字字符串和字符串值常量表达式都是实体。 String literals are defined in section 3.10.5 of the The Java™ Language Specification. 字符串文字在The Java™Language Specification的3.10.5节中定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM