main方法和JUnit中相同代码的执行不一致

ktecyv1j  于 2022-11-11  发布在  其他
关注(0)|答案(1)|浏览(155)
public static void main(String[] args) {
         String s1 = new String("1") + new String("1");
         s1.intern();
         String s2 = "11";
         System.out.println(s1 == s2); // This result is true.
    }
@Test
    public void test2(){
        String s1 = new String("1") + new String("1");
        s1.intern();
        String s2 = "11";
        System.out.println(s1 == s2); // This result is false.
    }

1.为什么我的代码在main方法中的执行结果与在JUnit单元测试中的执行结果不同

bxgwgixi

bxgwgixi1#

由于intern()的返回示例将被忽略,因此代码的行为将有所不同,具体取决于"11"字符串是否已被暂存。
请参阅intern()方法的文件:
调用intern方法时,如果池中已经包含一个等于此String对象的字符串(由equals(Object)方法确定),则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。
换句话说,当字符串还没有被暂存时调用s1.intern(),将返回相同的示例,也就是说,s1的示例将是被暂存的示例,因此s1 == "11"将导致true。否则,如果"11"已经被添加到池¹中,s1.intern()将返回已经在池中并且没有改变存储在s1中的引用的示例;因此s1 == "11"必须返回false
使用intern()方法的 * 正确 * 方法是使用返回的示例:

s1 = s1.intern();

这保证了s1始终是字符串池中的示例。

¹字符串将通过以前对具有相同内容的字符串调用intern()或在任何地方(包括任何库或标准类)使用"11"文本而添加到池中。

比较字符串是否已在池中时可能发生的情况。
@100表示指向示例的指针,数字(100)是该示例的虚构ID(或地址)。
"11"尚未在池中:

String s1 = new String("1") + new String("1");  // s1=@100
// the literal "1" is in the pool, but the resulting "11" is a new instance, not in/from the pool

s1.intern();  // s1=@100; returns @100
// "11" is not in the pool, so the instance (@100) is added to the pool and returned

String s2 = "11";  // s2=@100
// since there is already a "11" (@100) in the pool, it is used for the literal

System.out.println(s1 == s2);  // true since @100 == @100

"11" // @100已在池中,可能之前使用过该文字:

// somewhere else, already executed (main, standard java classes, junit, ...)
var x = "11";
// or
System.out.println("11");
// now "11" is in the string pool

...

String s1 = new String("1") + new String("1");  // s1=@101
// the literal "1" is in the pool, but the resulting "11" is a new instance, not from the pool

s1.intern();  // s1=@101; returns @100 (the value from the pool)
// "11" is in the pool, so the instance (@101) is NOT added to the pool and the pool instance @100 returned
// s1 is not changed and still contains @101, since the return value was not assigned to it

String s2 = "11";  // s2=@100
// since there is already a "11" (@100) in the pool, it is used for the literal

System.out.println(s1 == s2);  // false since @101 == @100

相关问题