Java字符串常量池问题

332 阅读2分钟

引语

字符串常量池问题,首先明确字符串的基本生成方法。

  1. 字面量直接赋值
  2. 字面量拼接赋值
  3. new String()
  4. new StringBuilder().toString()
  5. 变量拼接
  6. intern()方法

下面根据各方法进行分析。

代码

/**
 * @author Hugh Du
 */
public class StringTest {
    public static void main(String[] args) {

        // 1 字面量赋值,始终引用字符串常量池,没有则添加
        String str1= "abc"; //  
        
        // 2 字面量拼接赋值
        String str2 = "a" + "bc"; // 编译器会优化成字面量赋值"abc"

        // 3 new String()
        String str3 = new String("abc"); // new对象

        // 4 new StringBuilder()
        String str4 = new StringBuilder("abc").toString(); // 也是new对象

        // 5 变量拼接,底层是new StringBuilder()
        String str5 = "a";
        String str6 = str4 + "bc";
        String str7 = new String("a") + "bc";
        
        // 6 采用intern()方法
        String str8 = str7.intern();
        
        // 打印结果
        System.out.println(str1 == str2); //true
        System.out.println(str1 == str3); //false
        System.out.println(str1 == str4); //false
        System.out.println(str1 == str6); //false
        System.out.println(str1 == str6); //false
        System.out.println(str1 == str8); //true

    }
}

分析

  • 情况1、2,字面量直接复制和拼接赋值,编译器会进行优化,引用字符串常量池数据。
  • 情况3、4、5,对于new 对象,在堆中创建对象,先去常量池中查找,如果没有(即首次出现),则将引用添加到池中;如果有,不添加引用到池中,即与常量池无关。
  • 情况6,采用字符串intern()方法,会先去常量池中寻找,如果有,则返回引用;如果没有,则向常量池中添加首次出现的实例引用

结语

  • 字符串生成,主要分为字面量直接赋值和new对象。
  • 字面量直接赋值始终引用常量池数据。
  • 对于new对象,非首次出现时,不会引用常量池数据,在堆中新建一个对象。
  • intern()方法相当于强制使用字符串常量池。
  • new对象 和字面量直接赋值的执行顺序对结果没有影响.