在一个极端的情况下,允许在Java应用程序内检查字符串,然后再进行测试,但是每个字符串只能执行一次。与相同内容的字符串文字一起,可以检测到延迟加载:
public class Test { public static void main(String[] args) { test('h', 'e', 'l', 'l', 'o'); test('m', 'a', 'i', 'n'); } static void test(char... arg) { String s1 = new String(arg), s2 = s1.intern(); System.out.println('"'+s1+'"' +(s1!=s2? " existed": " did not exist")+" in the pool before"); System.out.println("is the same as "hello": "+(s2=="hello")); System.out.println("is the same as "main": "+(s2=="main")); System.out.println(); }}测试首先创建一个新的字符串实例,该实例在池中不存在。然后调用
intern()它并比较引用。有三种可能的方案:
如果池中存在相同内容的字符串,则将返回该字符串,该字符串必须是与不在池中的字符串不同的对象。
我们的字符串被添加到池中并返回。在这种情况下,两个引用是相同的。
具有相同内容的新字符串将被创建并添加到池中。然后,返回的引用将不同。
我们无法区分1和3,因此,如果JVM通常将新字符串添加到中的池中
intern(),那么我们就不走运了。但是,如果它添加了我们正在调用的实例
intern(),我们可以识别方案2,并确定该字符串不在池中,而是已添加为测试的副作用。
在我的机器上,它会打印:
"hello" did not exist beforeis the same as "hello": trueis the same as "main": false"main" existed beforeis the same as "hello": falseis the same as "main": true
同样在伊迪欧尼
显示尽管在稍后的代码中有字符串文字,但首次
"hello"输入该
test方法时该参数不存在
"hello"。因此,这证明了字符串文字是延迟解析的。由于我们已经
hello手动添加了字符串,因此具有相同内容的字符串文字将解析为相同的实例。
相反,
"main"字符串已经存在于池中,这很容易解释。Java启动器会搜索
main要执行的方法,因此,会将该字符串添加到池中作为副作用。
如果我们调换测试顺序
test('m', 'a', 'i', 'n'); test('h', 'e', 'l', 'l','o');的"hello"字符串字面量将在第一可用于
test调用和保留在池中,所以当我们在第二次调用测试该字符串将已经存在。



