1.4.用“”或构造函数创建String区别

在Java中,一个字符串可以通过下面两种方法创建。

String x = "abc";
String y = new String("abc");

用双引号创建和用构造函数创建有什么区别那?

双引号vs构造函数

这个问题可以通过下面两个简单的例子来回答。

String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True

a==b 为真,是因为在a和b都指向方法区域(保存常量池、字段和方法数据)中相同的字符串常量。
当一个字符串常量被创建多次,只有一份字符串的值被保存。这被叫做“string interning”
所有编译时候的字符串常量在java中都是被自动interned。

String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d);  // False
System.out.println(c.equals(d)); // True

c==d为假是因为c和d分别引用堆中不同点对象。不同的对象当然有不同的内存的引用。
如下图所示:

1.4.用“”或构造函数创建String区别_第1张图片
String构造区别

运行时String Interning

感谢LukasEder (他的建议如下):
String interning 即使两个字符串通过构造函数创建,在运行时候仍然可用。

String c = new String("abcd").intern();
String d = new String("abcd").intern();
System.out.println(c == d);  // Now true
System.out.println(c.equals(d)); // True

什么时候使用

因为字符串常量“abcd”也是个字符串类型,而且使用构造函数将创建个额外的对象。因此如果你需要创建一个引用字符串,应该使用双引号。
如果你需要在堆中创建一个新对象,那么应该使用构造函数。

译者说明

  • ""号定义的String是在编译时候确定的,然后在运行的时候装载在特定内存区。
  • new String()必须在运行时候申请内存。
  • new String().intern() Java会在常量池中查找是否有相同的字符串,如果有则返回常量池地址,如果没有将此字符串装载到常量池中,然后返回地址。
  • == 对于JavaString来说是比较内存地址是否相同,equals 是比较String的unicode序列是否相同。

你可能感兴趣的:(1.4.用“”或构造函数创建String区别)