我已阅读this answer关于如何检查字符串是否在Java中实现,但我不理解以下结果:
String x = args[0]; // args[0] = "abc";
String a = "a";
String y = a + "bc";
System.out.println(y.intern() == y); // true
但是如果我声明一个字符串文字:
String x = "abc";
String a = "a";
String y = a + "bc";
System.out.println(y.intern() == y); // false
此外,没有任何字符串文字,args[0]
似乎是直接实习:
// String x = "abc";
String y = args[0];
System.out.println(y.intern() == y); // true (???)
// false if the first line is uncommented
为什么y.intern() == y
会根据x
是否为文字而改变,即使对于使用命令行参数的示例也是如此?
我知道literal strings are interned at compile time,但我不明白为什么它会影响前面的例子。我还阅读了几个关于字符串实习的问题,例如 String Pool behavior , Questions about Java's String pool 和 Java String pool - When does the pool change? 。但是,它们都没有给出这种行为的可能解释。
修改
我错误地写道,在第三个例子中,如果声明了String x = "abc";
,结果不会改变,但确实如此。
答案 0 :(得分:6)
这是因为y.intern()
如果字符串之前未被实习则返回y
。如果字符串已经存在,则调用将返回已经存在的实例,该实例很可能与y
不同。
但是,所有这些都是高度依赖于实现的,因此在不同版本的JVM和编译器上可能会有所不同。
答案 1 :(得分:0)
实施细节可能有所不同。但这正是我所期望的行为。您的第一种情况意味着默认情况下不会禁用命令行参数。因此,y.intern()
在实习后将y
的引用返回。{/ p>
第二种情况是VM自动插入文字,以便y.intern()
返回x
的引用,这与y
不同。
最后一种情况再次发生,因为默认情况下没有任何内容,因此对intern()
的调用会返回对y
的引用
。
我认为实习生字符串更合理是合法的,但这是我理解的规范所要求的最小行为。