Java 字符串池和类型转换

标签 java string compiler-construction jvm

我的问题是关于 Java 处理字符串文字的方式。从 Java Language Specs (JLS) 中可以清楚地看出,字符串文字被隐式地驻留——换句话说,在堆的字符串常量池部分创建的对象,与调用 new String("whatever") 时创建的基于堆的对象形成对比。

似乎与 JLS 所说的不一致的是,当使用 String 连接和转换的常量 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 节:

> - Casts to primitive types and casts to type String

(实际上还有第二个原因。object 不是 final 因此不可能被视为 constant variable 。“基本类型或类型 的变量String,即 final 并使用编译时常量表达式(§15.28)初始化,称为常量变量。”——第 4.12.4 节。)

关于Java 字符串池和类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9865270/

相关文章:

java if语句测试输出错误

java - 逐个字母地显示单词

java - String.valueOf(Integer) 始终返回 1

c++ - 如何修复 Turbo C++ 错误 "Cannot open include file: graphics.h: no such files or director"

compiler-construction - 使用openjdk 1.6或sun jdk1.6编译代码

c++ - 使用模板函数和普通函数生成的代码之间的区别

java - 尝试使用 flink Kafka Consumer 消费时出现错误 "java.lang.NoSuchMethodError: org.apache.kafka.clients.consumer.KafkaConsumer.assign"

mysql - 从路径MYSQL中提取文件名

android - 单击提交按钮后在另一个页面中显示表单数据

java - 我可以在一个 Spring Integration 流程中使用 2 个聚合器吗?