[英]Java String pool and type casting
我的问题是关于Java处理字符串文字的方式。 从Java语言规范(JLS)可以清楚地看出,字符串文字是隐式实现的 - 换句话说,就是在堆的String常量池部分中创建的对象,与调用new String("whatever")
时创建的基于堆的对象形成对比。 new String("whatever")
。
似乎与JLS所说的不一致的是,当使用字符串连接创建一个新的String时,使用一个转换的常量String类型,根据JLS应该将其视为一个常量String,显然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 :(
}
}
编译时常量表达式中不允许强制转换为Object
。 唯一允许的强制转换是String
和基元。 JLS(Java SE 7版)第15.28节:
(实际上还有第二个原因。 object
不是final
所以不能考虑一个常量变量 。“一个原始类型或类型String
变量,是final
,用编译时常量表达式(第15.28节)初始化,被称为一个常数变量。“ - 第4.12.4节。)
似乎因为你在这里引用一个对象final String stringObject = (String) object;
,这不再是“编译时”常量,而是“运行时”常量。 从这里开始的第一个例子是:
String s = "lo";
String str7 = "Hel"+ s;
String str8 = "He" + "llo";
System.out.println("str7 is computed at runtime.");
System.out.println("str8 is created by using string constant expression.");
System.out.println(" str7 == str8 is " + (str7 == str8));
System.out.println(" str7.equals(str8) is " + str7.equals(str8));
字符串str7是在运行时计算的,因为它引用了另一个不是文字的字符串,所以通过该逻辑我假设尽管你使stringObject
final,但它仍然引用一个对象,因此无法在编译时计算。
从这里的java语言规范来看,它指出:
“当结果不是编译时常量表达式(第15.28节)时,字符串连接运算符+(第15.18.1节)隐式创建一个新的String对象。”
我找不到任何可以使用演员的例子,除了这个可怕的,可怕的例子:
System.out.println(hello == "hel" + ( String ) "lo");
这几乎没有任何合理用途,但由于上述情况,可能包括关于字符串强制转换的部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.