1

当我们在 Java 中编写

String S1 = "TestString";
String S2 = "TestString";

然后与 比较if(S1==S2),我们得到 true 作为布尔结果。相同的解释是字符串常量是在字符串池中创建的,因此它与 S1 和 S2 在这里引用的字符串常量相同。另外,如果我们写类似

String S1 = new String("TestString");

String S2 = new String("TestString");

然后与 进行比较if(S1==S2),我们得到错误。原因是 S1 和 S2 的引用不同,因为字符串文字是在堆中创建的。

我的问题是,在创建的构造函数中传递的字符串文字“TestString”在哪里?它与字符串文字/常量相同吗?因此应该像案例 1 一样在池中创建?如果是那么当我们在上面两个语句之后写类似的东西时

String S3 = "TestString";

这不应该创建一个新的字符串文字,比较if(S1==S3)应该给我真,但它给假。

所以我无法弄清楚这个字符串文字在何时何地在构造函数中被创建。

任何帮助将不胜感激。谢谢

4

2 回答 2

4

我的问题是,在创建的构造函数中传递的字符串文字“TestString”在哪里?它与字符串文字/常量相同吗?因此应该像案例 1 一样在池中创建?

正确,传递给构造函数调用的常量字符串new String("TestString")存储在字符串池中,就像在语句中一样String S1 = "TestString"

String S1 = new String("TestString");

String S2 = new String("TestString");

String S3 = "TestString";

在这种情况下S1==S3给出 false 因为S3是指由用于 的构造函数的参数创建的字符串文字S1,而S1是一个不同的字符串(因为它是使用构造函数创建的)。

于 2015-07-16T10:17:55.170 回答
0

如果(S1==S2),我们得到错误。

那是因为你有三个不同的字符串,S1、S2 和字符串文字。S1 和 S2 是 String 对象的副本,并且具有不同的引用。因此,它们都不==是彼此的。

我的问题是,在创建的构造函数中传递的字符串文字“TestString”在哪里?

它像所有其他对象一样在堆上创建(自 Java 6 起)它也被添加到 String intern() 池中,因此任何其他相同的 String 字面量都是相同的对象。

它与字符串文字/常量相同吗?

具有相同内容的所有字符串文字将是同一个对象。

字符串 S3 = "测试字符串"; 这不应该创建一个新的字符串文字

正确的。字符串文字已经创建。

比较 if(S1==S3) 应该给我真

我不知道为什么。S1 是字符串文字的副本,而不是字符串文字本身。

但它给出了错误。

正如预期的那样。

所以我无法弄清楚这个字符串文字在何时何地在构造函数中被创建。

在 Java 7 之前,字符串字面量是在加载类时创建的,在 Java 7+ 中,它是在首次使用时创建的。

如果 S1 和 S3 共享相同的字符串文字/常量

直到 Java 6,它们共享相同的底层 char[]。从 Java 7 开始,情况并非如此。String对象一直是并且将永远是不同的。

S1 具有引用,即它存储了实际存储常量“TestString”的位置的内存地址

S1是一个副本,因此它存储字符串文字副本的引用。

我仍然有一个问题,当我们比较 S1 和 S3 引用时,为什么它们不相等(它们必须持有相同的内存地址)

他们有不同的地址,这就是为什么==给出错误的原因。

S1 和 S2 都在堆栈上,它们包含它们从堆中引用的各个对象的地址值。所以 S1 和 S2 本身将占据不同的位置(地址)。

名义上S1S2有不同的位置和指向不同的位置。但是,当代码转换为机器代码以实际运行时,可以对其进行优化,使变量位于寄存器中,而不是在堆栈中,并且任何未使用的变量都将被丢弃。即它可能是不存在任何对象。

于 2015-07-17T16:53:52.510 回答