我的问题与Java处理字符串字面值的方式有关。从Java语言规范(JLS)中可以清楚地看出,字符串字面值被隐式地合并 - 换句话说,对象是在堆的字符串常量池部分创建的,而不是调用
与JLS所说的不符的是,当使用转换后的常量字符串类型进行字符串连接创建新字符串时,这应该根据JLS视为常量字符串,显然JVM会创建一个新的字符串对象而不是隐式合并它。我需要解释一下这种特殊行为是否是平台特定的行为,并感激您使内容更加通俗易懂。我正在运行Mac OSX Snow Leopard。
new String("whatever")
时创建的基于堆的对象。与JLS所说的不符的是,当使用转换后的常量字符串类型进行字符串连接创建新字符串时,这应该根据JLS视为常量字符串,显然JVM会创建一个新的字符串对象而不是隐式合并它。我需要解释一下这种特殊行为是否是平台特定的行为,并感激您使内容更加通俗易懂。我正在运行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 :(
}
}
String
的内容会被放入常量池中的规定?我的猜测是第二个表达式无法被常量折叠,因为编译器没有进行数据流分析来确定stringObject
是常量"lo"
。请注意,我的翻译保留了原意并尽可能地使语言通俗易懂,但不包含解释或其他额外信息。 - millimoose