【发布时间】:2012-03-26 00:27:41
【问题描述】:
我的问题是关于 Java 处理字符串文字的方式。从 Java 语言规范 (JLS) 中可以清楚地看出,字符串字面量是隐式实习的 - 换句话说,在堆的字符串常量池部分中创建的对象,与调用 @987654321 时创建的基于堆的对象相反@。
似乎与 JLS 所说的不一致的是,当使用带有强制转换的常量字符串类型的字符串连接创建新字符串时,根据 JLS,它应该被视为常量字符串,显然 JVM 是创建一个新的 String 对象,而不是隐式地实习它。我很欣赏有关此特定行为的任何解释,以及这是否是特定于平台的行为。我在 Mac OSX Snow Leopard 上运行。
public class Test
{
public static void main(String args[])
{
/*
Create a String object on the String constant pool
using a String literal
*/
String hello = "hello";
final String lo = "lo"; // this will be created in the String pool as well
/*
Compare the hello variable to a String constant expression
, that should cause the JVM to implicitly call String.intern()
*/
System.out.println(hello == ("hel" + lo));// This should print true
/*
Here we need to create a String by casting an Object back
into a String, this will be used later to create a constant
expression to be compared with the hello variable
*/
Object object = "lo";
final String stringObject = (String) object;// as per the JLS, casted String types can be used to form constant expressions
/*
Compare with the hello variable
*/
System.out.println(hello == "hel" + stringObject);// This should print true, but it doesn't :(
}
}
【问题讨论】:
-
不要对字符串使用 ==,使用 String1.equals(string2)
-
@dann.dev:我认为你错过了问题的重点。
-
整件事是关于在哪里创建对象,而不是创建什么对象。
-
您能否链接到 JLS 中指出转换为
String的表达式将被放入常量池的部分?我的预感是第二个表达式根本不能被常量折叠,因为编译器没有进行数据流分析来确定stringObject是常量"lo"。 -
@dann.dev OP 不是在问如何比较字符串,而是在问常量字符串表达式在 Java 中是如何工作的。
标签: java string compiler-construction jvm