Java 中具有相同值的字符串?

2022-09-03 09:21:03

一个快速而令人困惑的问题。如果A类和B类内部有这个:-

String name="SomeName"; 

并且两个类都被实例化了,两个实例是否都引用了变量“name”的相同内存位置,比如当我们执行此操作时,objA.name 或 objB.name?它具有值“SomeName”,并且由于字符串是不可变的,因此同一JVM的两个类的几个实例重复使用相同的变量?我在网上的某个地方读到,除非有

String example=new String("something"); 

,前一个声明始终创建一个副本,直到其所有应用程序都终止以回收内存。注意:我看到几个答案,我指望哪一个,有人可以得出结论吗?谢谢大家的努力,谢谢。


答案 1

是的,如果您创建两个字符串,例如:

String a = "Hello";
String b = "Hello";

它们将是完全相同的对象。您可以自己测试它

System.out.println(a == b);

如果它们是同一对象,则它们对字符数组的内部引用将完全相同。

现在,如果你这样做了,它就不会有相同的引用,因为它(内部)是使用StringBuilder构建的。String c = "Hell" + "o";

这里有很多好的信息。

相关部分有(注:以下内容是从该网站复制的):


如前所述,有两种方法可以构造字符串:通过分配 String 文本进行隐式构造,或通过 new 运算符和构造函数显式创建 String 对象。例如

String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object

Strings

Java设计了一种特殊的机制来保存字符串文本 - 在所谓的字符串公共池中。如果两个 String 文本具有相同的内容,它们将在公用池中共享相同的存储位置。采用此方法是为了节省常用字符串的存储空间。另一方面,通过 new 运算符创建的 String 对象保留在堆中。堆中的每个 String 对象都有自己的存储,就像任何其他对象一样。即使两个 String 对象具有相同的内容,堆中也不会共享存储。可以使用 String 类的方法 equals() 来比较两个字符串的内容。可以使用关系相等运算符“==”来比较两个对象的引用(或指针)。研究以下代码:

s1 == s1;         // true, same pointer
s1 == s2;         // true, s1 and s1 share storage in common pool
s1 == s3;         // true, s3 is assigned same pointer as s1
s1.equals(s3);    // true, same contents
s1 == s4;         // false, different pointers
s1.equals(s4);    // true, same contents
s4 == s5;         // false, different pointers in heap
s4.equals(s5);    // true, same contents

编辑以添加:运行此 SSCE 以测试不同类中两个常量字符串之间的引用相等性:

class T {
  String string = "Hello";

  public static void main(String args[]) {
    T t = new T();
    T2 t2 = new T2();
    System.out.println(t.string == t2.string);
  }
}


class T2 {
  String string = "Hello";
}

打印出 。true


答案 2

如果“某物”从字面上硬编码到源代码中,则两个变量将指向相同的内存中 String 对象。