为什么这些字符串没有指向 java 中的同一个对象?

olt*_*o93 1 java string pool

我知道如果我有 2 个具有相同值的字符串变量,由于 java 字符串池,它们指向同一个字符串对象。

下面是一个例子:

String test = "1234";
String test2 = "1234";
    
System.out.println(test == test2);
System.out.println("1234" == test2);
Run Code Online (Sandbox Code Playgroud)

输出如下:

true
true
Run Code Online (Sandbox Code Playgroud)

但是如果我有以下代码,它会打印出它们不是同一个对象

String test = "1234";
int i = 1234;
String s = "" + i;
    
System.out.println(test == s);
System.out.println("1234" == s);
Run Code Online (Sandbox Code Playgroud)

输出:

false
false
Run Code Online (Sandbox Code Playgroud)

任何人都会向我解释这种行为的原因吗?

hev*_*ev1 5

"" + i;不是一个常量表达式,所以它不被实习。如果i是 final 或直接写为"" + 1234,则该值将被实习。

§3.10.5。字符串文字

此外,字符串字面量始终引用类 String 的同一个实例。这是因为字符串文字 - 或者更一般地说,作为常量表达式(第 15.28 节)的值的字符串 - 使用 String.intern 方法被“嵌入”以便共享唯一实例。

第 15.28 条。常量表达式

常量表达式是表示原始类型的值或不会突然完成并且仅使用以下内容组成的字符串的表达式:
  • 原始类型的文字和字符串类型的文字(§3.10.1、§3.10.2、§3.10.3、§3.10.4、§3.10.5)
  • 转换为原始类型并转换为 String 类型(第 15.16 节)
  • 一元运算符 +、-、~ 和 ! (但不是 ++ 或 --)(§15.15.3、§15.15.4、§15.15.5、§15.15.6)
  • 乘法运算符 *、/ 和 %(第 15.17 节)
  • 加法运算符 + 和 -(第 15.18 节)
  • 移位运算符 > 和 >>>(第 15.19 节)
  • 关系运算符 和 >=(但不是 instanceof)(第 15.20 节)
  • 相等运算符 == 和 !=(第 15.21 节)
  • 按位和逻辑运算符 &、^ 和 | (第 15.22 节)
  • 条件与运算符 && 和条件或运算符 || (第 15.23 节、第 15.24 节)
  • 三元条件运算符 ? :(第 15.25 节)
  • 括号表达式(第 15.8.5 节),其包含的表达式是一个常量表达式。
  • 引用常量变量(第 4.12.4 节)的简单名称(第 6.5.6.1 节)。
  • TypeName 形式的限定名称(第 6.5.6.2 节)。引用常量变量的标识符(第 4.12.4 节)。