经典面试题:运行时常量池的问题(JDK1.8环境)

以下代码,控制台打印的结果是什么?

public class TestDemo {
    
    @Test
    public void test01() {
        String str1 = new StringBuilder("hello").append("World").toString();
        System.out.println(str1.intern());
        System.out.println(str1 == str1.intern());

        String str2 = new StringBuilder("ja").append("va").toString();
        System.out.println(str2.intern());
        System.out.println(str2 == str2.intern());

        String str3 = new StringBuilder("ab").append("c").toString();
        System.out.println(str3.intern());
        System.out.println(str3 == str3.intern());
        
        String str4 = new StringBuilder("abc").toString();
        System.out.println(str4.intern());
        System.out.println(str4 == str4.intern());
    }
    
}

控制台打印的结果

helloWorld
true
java
false
abc
true
abc
false

分析

String.intern()
是一个Native方法,它的作用是:如果字符常量池中已经包含一个等于此String对象的字符串,则返回常量池中字符串的引用,否则,将新的字符串放入常量池,并返回新字符串的引用。
intern()有两个作用,第一个是将字符串字面量放入常量池(如果池没有的话),第二个是返回这个常量的引用

  • 采用new 创建的字符串对象不进入字符串池;
  • 字符串相加的时候,都是静态字符串的结果会添加到字符串池,如果其中含有变量则不会进入字符串池中。
  1. 第一个:"helloWorld"字符串new出来之后在运行时常量池中没有,所以调用intern()方法会将这个对象存入常量池中,并返回地址。所以str1 == str1.intern() 为true;
  2. 第二个:"java"在类加载机制过程中已经加载到常量池中,new出来的"java"对象与intern()方法从常量池返回的地址不一样,所以str2 == str2.intern() 为false;
  3. 第三个:与第一个是一样的,"abc"字符串new出来之后在运行时常量池中没有,所以调用intern()方法会将这个对象存入常量池中,并返回地址。所以str3 == str3.intern() 为true;;
  4. 第四个:String str4 = new StringBuilder("abc").toString()这个语句,首先会去常量池查找有没有“abc”这个字符串,有则只创建new StringBuilder("abc").toString()对象并把地址赋给str4,没有则创建“abc”和new StringBuilder("abc").toString()两个对象,所以不管如何,str4引用地址是指向new StringBuilder("abc").toString()这个新创建的对象,而str4.intern()返回的是“abc”的引用地址,str4 == str4.intern() 为false
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容