我有一个奇怪的字符串池行为的问题.我==用来比较相同的字符串,以确定它们是否在池中.
public class StringPoolTest {
public static void main(String[] args) {
new StringPoolTest().run();
}
String giveLiteralString() {
return "555";
}
void run() {
String s1 = giveLiteralString() + "";
System.out.println("555" == "555" + "");
System.out.println(giveLiteralString() == giveLiteralString() + "");
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
true
false
Run Code Online (Sandbox Code Playgroud)
这对我来说是个大惊喜.有人能解释一下吗?我认为这个问题发生在编译时.但是为什么添加""到String会产生任何差异呢?
Mar*_*nik 110
"555" + ""
Run Code Online (Sandbox Code Playgroud)
是一个编译时常量,而
giveLiteralString() + ""
Run Code Online (Sandbox Code Playgroud)
不是.因此,前者只编译为字符串常量"555",后者编译成实际的方法调用和连接,从而产生一个新的String实例.
在运行时通过串联计算的字符串是新创建的,因此是不同的.
Evg*_*eev 31
反编译此行后
System.out.println("555" == "555" + "");
Run Code Online (Sandbox Code Playgroud)
我有这个字节码
LINENUMBER 8 L0
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ICONST_1
INVOKEVIRTUAL java/io/PrintStream.println(Z)V
...
Run Code Online (Sandbox Code Playgroud)
这相当于
System.out.println(true);
Run Code Online (Sandbox Code Playgroud)
这意味着表达式"555" == "555" + ""编译为布尔值true.
对于giveLiteralString() == giveLiteralString() + ""javac构建了这个字节码
LINENUMBER 8 L0
INVOKESTATIC Test1.giveLiteralString()Ljava/lang/String;
NEW java/lang/StringBuilder
DUP
INVOKESTATIC Test1.giveLiteralString()Ljava/lang/String;
INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
IF_ACMPNE L1
...
Run Code Online (Sandbox Code Playgroud)
这相当于
if (giveLiteralString() == new StringBuilder(giveLiteralString()).append("").toString()) {
...
Run Code Online (Sandbox Code Playgroud)
这将永远产生错误,因为在这里我们比较2个disctinct对象.
| 归档时间: |
|
| 查看次数: |
2268 次 |
| 最近记录: |