繁体   English   中英

Java字符串池和类型转换

[英]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节:

> - 转换为基本类型并转换为String类型

(实际上还有第二个原因。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM