两者有什么区别

String str = new String("abc");

and

String str = "abc";

当前回答

在第一种情况下,创建了两个对象。

在第二种情况下,它只是一个。

尽管两种方式str都指向abc。

其他回答

字符串对象和字符串文字之间有细微的区别。

String s = "abc"; // creates one String object and one reference variable

在这个简单的例子中,“abc”将进入池,s将指向它。

String s = new String("abc"); // creates two objects,and one reference variable

在本例中,因为我们使用了new关键字,Java将创建一个新的String对象 在普通(非池)内存中,和s将指向它。此外,字面上的“abc”将 放在水池里。

根据String类文档,它们是等价的。

String(String original)的文档还说:除非需要original的显式副本,否则使用此构造函数是不必要的,因为String是不可变的。

寻找其他的回答,因为Java文档似乎是误导性的:(

以下是一些比较:

String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");

System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); //true

System.out.println(s1 == s3);   //false
System.out.println(s1.equals(s3)); //true

s3 = s3.intern();
System.out.println(s1 == s3); //true
System.out.println(s1.equals(s3)); //true

当调用intern()时,引用将被更改。

长一点的答案在这里,所以我给你一个短一点的。

当你这样做的时候:

String str = "abc";

你在String上调用intern()方法。该方法引用String对象的内部池。如果调用intern()的String已经在池中,则将该String的引用赋值给str。如果没有,则将新String放入池中,并将其引用赋值给str。

给定以下代码:

String str = "abc";
String str2 = "abc";
boolean identity = str == str2;

当你通过==来检查对象的同一性(你实际上是在问:这两个引用是否指向同一个对象?),你得到true。

但是,您不需要使用intern()字符串。你可以这样强制创建一个堆上的新对象:

String str = new String("abc");
String str2 = new String("abc");
boolean identity = str == str2;

在本例中,str和str2是对不同对象的引用,它们都没有被合并,因此当您使用==测试对象标识时,将得到false。

在良好的编码实践方面:不要使用==来检查String是否相等,而是使用.equals()来代替。

由于字符串是不可变的,当你这样做时:

String a = "xyz"

在创建字符串时,JVM在字符串池中搜索是否已经存在一个字符串值“xyz”,如果存在,'a'将只是该字符串的引用,并且不会创建新的string对象。

但如果你说:

String a = new String("xyz")

强制JVM创建一个新的String引用,即使"xyz"在它的池中。

要了解更多信息,请阅读这篇文章。