详解String intern方法

  • 一,弄清楚String对象的特点:

不可变的(final);

 

  • 二,弄清楚+号和StringBuilder:

+号操作分n种情况,但只有一种情况等同于直接字符串,那就是常量值相加,像这样:

String str = "abc" + 123; 等同于String str = "abc123";

String str = "abc" + "def"; 等同于String str = "abcdef";

指令为证: 

      stack=1, locals=2, args_size=0
         0: ldc           #64                 // String abc123
         2: astore_0
         3: ldc           #66                 // String abcdef
         5: astore_1

除此之外,其他的相加一律视为StringBuilder对象,例如:

int i = 1;

String str = "abc" + i;

查看这两句的指令:

         0: bipush        123
         2: istore_0
         3: new           #64                 // class java/lang/StringBuilder
         6: dup
         7: ldc           #66                 // String abc
         9: invokespecial #68                 // Method java/lang/StringBuilder."":(Ljava/lang/String;)V
        12: iload_0
        13: invokevirtual #69                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        16: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        19: astore_1
        20: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;

可以看到,其最终是通过StringBuilder来append字符串的。

 

  • 三,弄清楚常量池在不同JDK版本下的存储位置

这一点对了解intern很重要,从JDK1.7开始,常量池就不放在永久代的方法区了,而是放在了堆中。同时,常量池也能够存储引用对象(指向堆地址)。

 

OK,了解了上面基础知识,再开始看intern,正所谓磨刀不误砍柴工。

 

1,先来个简单的例子

        String s1 = new String("abc");
        System.out.println(s1 == s1.intern());

输出:false

解释:这个很简单,可以看到s1指向堆中地址,而s1.intern()则返回常量池中的地址。

详解String intern方法_第1张图片1.6

详解String intern方法_第2张图片1.7

2,常见题目

String s1 = new String("a") + new String("b");

s1.intern();

String s2 = "ab";

Sysout.out.println(s1== s1.intern()); 

Sysout.out.println(s1== s2);

Sysout.out.println(s1.intern() == s2); 

详解String intern方法_第3张图片

解释:String s1 = new String("a") + new String("b"); 这句话执行完,是不会往常量池中加常量对象ab的,只有a,b两个会加到常量池中。——这个前提要清楚。

如果是JDK1.6,见左边图,会在常量池中加上ab对象,注意:是ab的值,不是引用;

如果是JDK1.7,见右边图,会在常量池中加上指向堆地址的引用对象。

综上,比较==,只要看实线箭头最终指向哪里就可以了。

你可能感兴趣的:(java)