下面这两种说法有什么不同?

String s = "text";

String s = new String("text");

当前回答

把“bla”想象成一个魔法工厂,就像Strings.createString(“bla”)(pseudo)。工厂保存了所有以这种方式创建的字符串池。

如果它被调用,它会检查池中是否已经有这个值的字符串。如果为真,则返回此string对象,因此以这种方式获得的字符串确实是同一个对象。

如果不是,它在内部创建一个新的字符串对象,将其保存在池中,然后返回它。因此,当下次查询相同的字符串值时,它将返回相同的实例。

手动创建新的String("")通过绕过字符串字面量池来覆盖这种行为。因此,应该始终使用equals()检查相等性,它比较字符序列,而不是对象引用相等性。

其他回答

新的字符串(“文本”); 显式地创建String对象的一个新的引用不同的实例;字符串s = "text";可以重用字符串常量池中的实例(如果有)。

你很少会想要使用新的String(anotherString)构造函数。来自API:

String(String original):初始化新创建的String对象,使其表示与参数相同的字符序列;换句话说,新创建的字符串是参数字符串的副本。除非需要original的显式副本,否则使用此构造函数是不必要的,因为字符串是不可变的。

相关问题

Java字符串:“字符串s =新字符串(“愚蠢的”);” 字符串是Java中的对象,所以为什么我们不使用' new '来创建它们呢?


什么是指涉区别

检查下面的代码片段:

    String s1 = "foobar";
    String s2 = "foobar";

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

    s2 = new String("foobar");
    System.out.println(s1 == s2);      // false
    System.out.println(s1.equals(s2)); // true

两个引用类型上的==是引用标识符比较。两个相等的对象不一定是==。在引用类型上使用==通常是错误的;大多数时候应该用等号代替。

尽管如此,如果出于某种原因需要创建两个equals而不是== string,则可以使用新的string (anotherString)构造函数。然而,需要再次说明的是,这是非常奇怪的,而且很少是故意的。

参考文献

JLS 15.21.3引用相等操作符==和!= 类对象-布尔对象(等于)

相关问题

Java字符串。等于和== 我如何比较字符串在Java?

String str = new String("hello")

它将检查字符串常量池是否已经包含字符串“hello”? 如果存在,则不会在String常量池中添加条目。如果不存在,它将在String常量池中添加一个条目。

对象将在堆内存区域中创建,str引用指向在堆内存位置中创建的对象。

如果你想要str引用String常量池中包含的点对象,则必须显式调用str.intern();

String str = "world";

它将检查字符串常量池是否已经包含字符串“hello”? 如果存在,则不会在String常量池中添加条目。如果不存在,它将在String常量池中添加一个条目。

在上述两种情况下,str引用指向常量池中存在的字符串“world”。

@Braj:我想你已经提到了另一种方式。如果我错了,请指正

逐行创建对象:

字符串 str1 = new String(“java5”)

   Pool- "java5" (1 Object)

   Heap - str1 => "java5" (1 Object)

String str2 = "java5"

  pool- str2 => "java5" (1 Object)

  heap - str1 => "java5" (1 Object)

字符串 str3 = 新字符串(str2)

  pool- str2 => "java5" (1 Object)

  heap- str1 => "java5", str3 => "java5" (2 Objects)

String str4 = "java5"

  pool - str2 => str4 => "java5" (1 Object)

  heap - str1 => "java5", str3 => "java5" (2 Objects)

在字符串字面值池中创建任何字符串字面值,并且池不允许任何副本。因此,如果两个或多个字符串对象初始化为相同的字面值,那么所有对象将指向相同的字面值。

String obj1 = "abc";
String obj2 = "abc";

"obj1"和"obj2"将指向相同的字符串字面量,字符串字面量池将只有一个"abc"字面量。

当我们使用new关键字创建String类对象时,这样创建的字符串存储在堆内存中。任何作为参数传递给string类的构造函数的字符串字面值都存储在字符串池中。如果我们使用new操作符使用相同的值创建多个对象,每次都会在堆中创建一个新对象,因为应该避免使用这个new操作符。

String obj1 = new String("abc");
String obj2 = new String("abc");

"obj1"和"obj2"将指向堆中两个不同的对象,字符串字面量池将只有一个"abc"字面量。

关于字符串的行为还有一点值得注意,那就是任何对字符串进行的赋值或连接都会在内存中创建一个新对象。

String str1 = "abc";
String str2 = "abc" + "def";
str1 = "xyz";
str2 = str1 + "ghi";

在上面的例子中: 第1行:“abc”字面值存储在字符串池中。 第2行:"abcdef"字面值存储在字符串池中。 第3行:一个新的“xyz”字面值存储在字符串池中,“str1”开始指向这个字面值。 第4行:由于该值是通过附加到另一个变量而生成的,因此结果存储在堆内存中,被附加的字面量“ghi”将在字符串池中检查是否存在,并将被创建,因为在上述情况下它不存在。

尽管从程序员的角度来看,它们看起来是一样的,但它对性能有很大的影响。你几乎总是想用第一种形式。