20220629_String 类的 intern 方法

20220629_String类的intern方法


好久不见!

好久不见!!!

最近事情挺多,还好负责的迭代快上线了可以摸一下。在公司,外包仔可不敢用公司电脑登录摸鱼派。


正文

环境是JDK1.8,然后有这么一段代码:

/**
 * @author LLaamar
 * @date 2022/6/29 20:17
 */
public class InternTest {
    public static void main(String[] args) {
        String str = new StringBuilder().append("摸鱼").toString();
        System.out.println(str == str.intern());
        System.out.println("————————————————分割线————————————————");
        String str2 = new StringBuilder().append("摸鱼").append("π").toString();
        System.out.println(str2 == str2.intern());
    }
}

执行结果如下:

false
————————————————分割线————————————————
true

很好奇,为什么?

不就是多了次append() ?为啥一个false一个true

看到这里的可以停下来思考下为什么,没看到的可以看到以后再思考。

我翻了**append()的源码没找到答案,翻了toString()**的源码也没找到答案,发到公司后端群里引起激烈讨论,大家纷纷开始摸鱼讨论,最终在一位不知名大佬的帮助下找到答案——intern方法。

点进intern方法的源码可以看到,除了一串英文注释啥也没有。。。

image-20220629203723249.png

大佬解释道:还是看下注释吧。。。

image-20220629203817322.png

注释一长串,翻译也是有点烂,想必大家也懒得看(还有点押韵,skr~)

大致意思是,intern方法执行时会去查看常量池中是否已经有该字符串常量的引用,如果有,则返回。如果没有,就在常量池中创建引用,指向堆,再返回字符串在常量池中的引用。

所以,上面的代码可以有如下的注释:

/**
 * @author LLaamar
 * @date 2022/6/29 20:17
 */
public class InternTest {
    public static void main(String[] args) {
        // str是通过new声明的对象,存在于堆中
        // 常量"摸鱼"被显示声明,此时"摸鱼"将存在于常量池中,并且常量"摸鱼"与str没有关系
        String str = new StringBuilder().append("摸鱼").toString();
        // str.intern()将返回常量池中的常量"摸鱼",此时==结果为false
        System.out.println(str == str.intern());
        System.out.println("————————————————分割线————————————————");
        // str是通过new声明的对象,存在于堆中,str的内容是"摸鱼π"
        // 常量"摸鱼"、"π"被显示声明,存在于常量池中
        String str2 = new StringBuilder().append("摸鱼").append("π").toString();
        // 常量池中不存在常量"摸鱼π",则str2.intern()将会在常量池中创建引用,该引用指向堆中的str2,返回str2的地址,此时==结果为true
        System.out.println(str2 == str2.intern());
    }
}

说起来是有点绕的,最后留个思考题:

public class InternTest {
    public static void main(String[] args) {
        String tk = "摸鱼π";
        String str3 = new StringBuilder().append("摸鱼").append("π").toString();
        System.out.println(str3 == str3.intern());
    }
}

不懂的可以多看看上面的解释,懂的可以在评论区装个B。

那就这样,我们下期,再见。


努力让自己不那么菜

欲速则不达,每天进步一点点。