来自String类的实习方法的javaDocs:
当调用实习方法时,如果池已包含 字符串等于此字符串对象由equals(Object)确定 方法,然后返回池中的字符串。否则,这个 String对象被添加到池中以及对此String的引用 返回对象。
考虑以下用例:
String first = "Hello";
String second = "Hello";
System.out.println(first == second);
String third = new String("Hello");
String fourth = new String("Hello");
System.out.println(third == fourth);
System.out.println(third == fourth.intern());
System.out.println(third.intern() == fourth);
System.out.println(third == fourth);
System.out.println(third.intern() == fourth.intern());
System.out.println(third.intern() == first);
String fifth = new String(new char[]{'H','e','l', 'l', 'o'});
String sixth = new String(new char[]{'H','e','l', 'l', 'o'});
System.out.println(fifth == fifth.intern());
System.out.println(sixth == sixth.intern());
String seven = new String(new char[]{'H','e','l', 'l', 'o' , '2'});
String eight = new String(new char[]{'H','e','l', 'l', 'o' , '2'});
System.out.println(seven == seven.intern());
System.out.println(eight == eight.intern());
有人可以解释为什么 seven == seven.intern()
true ,而以下是 false :
System.out.println(fifth == fifth.intern());
System.out.println(sixth == sixth.intern());
System.out.println(eight == eight.intern());
答案 0 :(得分:2)
七是你第一次使用字符串'hello2'。因此intern
所做的是将您的字符串插入池中(并返回它)。因为它等于你的七个。
当您使用8时,字符串已经在池中(之前运行seven.intern()
,因此当您执行eight == eight.intern()
时,您将获得新创建的等式左侧eight
1}}字符串,右边是由池中七个创建的字符串,它们不是相同的
答案 1 :(得分:1)
因为当您使用new String()
语法时,您没有利用字符串池,而是创建一个新的String实例,无论它是否在池中。
故事的道德......永远不要使用new String()
您受JVM的支配,JVM可以选择是否已经存在“内化”字符串,或者应该将其内化。 更具体地说:
为了派生字符串文字,Java虚拟机检查CONSTANT_String_info结构给出的代码点序列。
如果先前在类String的实例上调用了String.intern方法,该类包含与CONSTANT_String_info结构给出的Unicode代码点序列相同的Unicode代码点序列,则字符串文字派生的结果是对同一个实例的引用class String。 否则,将创建一个类String的新实例,其中包含CONSTANT_String_info结构给出的Unicode代码点序列;对该类实例的引用是字符串文字派生的结果。最后,调用新String实例的intern方法。
答案 2 :(得分:0)
pczeus是正确的。更多信息:
第五个是包含值“Hello”的新字符串(未检查池)。当你intern()它时,返回值是第四个(第一次出现“Hello”被实习),它不等于第五个。
第六个答案相同。
七是第一次出现“Hello2”并且在你调用'seven == seven.intern()'之前它没有被实习。由于它在那一刻被实习,因此intern()的返回值为7。
八是“Hello2”的另一个新实例。当它被实习时,返回值为7,而不是8
答案 3 :(得分:0)
String seven = new String(new char[]{'H','e','l', 'l', 'o' , '2'});
文字“Hello2
”将导致创建字符串常量池中的对象。新String将在堆上创建一个新的String对象,并带有文本对象内容的副本。
你永远不应该像这样创建String对象,因为它不必要且效率低下。当您执行System.out.println(seven == seven.intern());
时,它将打印true
。
现在,当您执行System.out.println(eight == eight.intern());
字符串时,字符串池已经存在,因此它将打印false
。