Java String直接赋值和通过new创建的区别

260 阅读2分钟

String Literal vs new String()

  • 字面量最多只会创建一个对象(如果字符串常量池有相同的字符串返回该字符串地址,如果没有创建一个并返回地址),通过字面量创建的String 变量引用的是字符串常量池值中的地址。

  • new最少创建一个对象,多了创建两个对象(如果字符串常量池中有相同的字符串,将字符串的值拷贝到heap中分配的内存中,没有相同的字符串先在字符串常量池中创建字符串再执行拷贝到heap中)。new返回的对象创建中heap中,变量引用heap中的值的地址。

在Java中String Literal 是保存在字符串常量池中的。假设我们定义了多个String literal,变量 a b aa 都是 String literal,bbnew出来的变量。字面量创建的变量引用常量池对象的地址,new出来的变量引用heap中对象的地址。

String a = "a";
String aaa = String.valueOf('a');
String aa = "a";
String b = "b";
String bb = new String("b");
System.out.println("a == aa is " + (a == aa) + "  a 与 aa 的引用地址相同"); // true
System.out.println("a == aaa is " + (a == aaa) + " a 与 aaa 的引用地址不相同"); // false
System.out.println("b == bb is " + (b == bb) + " b 与 bb 的引用地址不同"); // false
  • 为什么说new出的对象先从字符串常量池中找对应的字符串。查看String 的构造方法,可以看出需要一个String literal,而String literal都是保存在字符串常量池中的,所以先从字符串常量池中找对应的字符串。
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

valueOf(): 也是返回一个堆中的新的字符串

public static String valueOf(char c) {
    char data[] = {c};
    return new String(data, true);
}

引入问题,什么是常量池,在内存中的哪个区域呢?