代码之家  ›  专栏  ›  技术社区  ›  Noel M

Java字符串什么时候内网?

  •  18
  • Noel M  · 技术社区  · 15 年前

    灵感来自 this question ,我很肯定Java String 类是在运行时而不是编译时被占用的——当然这只是一个事实,即类可以在不同的时间被编译,但在运行时仍然指向相同的引用。

    我似乎找不到任何证据来支持这一点。有人能证明这一点吗?

    2 回复  |  直到 9 年前
        1
  •  17
  •   Jon Skeet    13 年前

    • 如果对同一字符串常量的两个引用出现在同一个类中,我希望类文件只包含一个常量池条目。这不是严格意义上的 必修的 为了确保只有一个 String 在JVM中创建的对象,但这显然是要进行的优化。这实际上不是实习,只是不断优化。
    • 加载类时,类的字符串池将添加到实习生池中。这是“真正的”实习。

    (我模模糊糊地记得,Java7在“小jar文件”方面的工作包括一个用于整个jar文件的字符串池。。。但我可能大错特错。)

    编辑:JVM规范第5.1节, "The Runtime Constant Pool" 详细说明如下:

    要派生字符串文本,Java 虚拟机检查序列 由 常量字符串信息结构。

    • 以前在实例上调用过 包含序列的类字符串 与相同的Unicode字符数 由常量字符串info给出的 结构,然后是字符串的结果 文字派生是对 类字符串的同一个实例。

    • 否则,类的新实例 创建的字符串包含 给定的Unicode字符序列 通过常量字符串信息结构; 该类实例是 字符串文字派生。最后, 新字符串的intern方法 实例被调用。

        2
  •  0
  •   Glen Best    13 年前

    JLS和JVM规范指定javac对类文件的编译,这些类文件包含常量声明(在常量池中)和代码中的常量用法(javac可以内联为原语/对象引用值)。对于编译时的字符串常量,编译器生成代码来构造字符串实例,并为它们调用String.intern(),这样JVM将自动调用字符串常量。这是一个 行为的 JLS要求:

    http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28

    String类型的编译时常量表达式总是“interned”,以便使用String.intern方法共享唯一的实例。

    但是这些规范既没有概念,也没有定义任何特定的字符串内部池结构/引用/句柄,无论是编译时还是运行时(当然,一般来说,JVM规范并不要求对象具有任何特定的内部结构: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.7

    之所以没有提到intern池结构,是因为它们完全由String类处理。intern pool是String类的私有静态/类级结构(JLS&未指定);JVM规范;javadoc)。