【问题标题】:Java class constant pool duplicates?Java类常量池重复?
【发布时间】:2013-05-17 05:50:11
【问题描述】:

我用javap 反编译了一个类,我在常量池部分看到了一些重复项,如下所示:

 #19 = Class              #350          //  java/lang/StringBuilder
... Some other class constants here
#318 = Class              #350          //  java/lang/StringBuilder

Methodrefs 只引用其中一个:

 #20 = Methodref          #19.#351      //  java/lang/StringBuilder."<init>":()V
 #22 = Methodref          #19.#353      //  java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 #24 = Methodref          #19.#355      //  java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
 #25 = Methodref          #19.#356      //  java/lang/StringBuilder.toString:()Ljava/lang/String;
#110 = Methodref          #19.#445      //  java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;

根据The class File Format,这个类是否正确?我认为每个 Class 只被提及一次,稍后由它在字节码部分的索引来引用。

$ javac -version
javac 1.7.0_15

另一个奇怪的事情是在 javac Pool.java 中表示常量池的类的源代码中。这表明如果对象已经存在(在 HashMap 的帮助下),它将不会将对象放入池中。我想知道这些类的equals()/hashCode()方法是否正确实现。

【问题讨论】:

    标签: java javac


    【解决方案1】:

    注意:根据JENKINS-22525 看来,虽然具有此类重复的类文件在技术上是合法的,但 IBM 的 J9 VM 在某些情况下会拒绝加载其内部类,观察到

    java.lang.IncompatibleClassChangeError: incompatible InnerClasses attribute between …
    

    【讨论】:

      【解决方案2】:

      你是对的。 Constant pool 不需要重复条目。一个类在常量池中应该只有 1 个条目。

      这绝对是一个错误。看一下这个。有人将此记录为错误并已得到确认>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6746955

      答案已更新:

      这里我还要指出一点,添加重复条目没有任何意义,因为它增加了类文件的字节大小,破坏了 java 类文件的紧凑性、可移植性和更快的网络移动性的主要目的。类文件应尽可能紧凑。

      顺便说一下,类文件是有效的,因为它遵循定义的类文件格式。但它不是一个理想的。

      我忘了,回答你的第二个问题:

      JVM 为外观相似 的对象分配相同的哈希码,但它们仍然是不同的。 JVM 永远不会创建两个相同的对象,除非它们都引用同一个对象。哈希码只不过是一个分区系统。看起来相似的对象被放置在同一个分区中,以便在搜索特定对象时遍历时间变得更少。哈希码只不过是指向那个小分区的指针。

      只是因为不可能为每个新对象分配不同的哈希码(因为对象的数量可能超过可能创建的唯一哈希码的数量。请参阅哈希算法中可能发生的冲突),您可能会发现不同的对象具有相同的哈希码。但问题是,内存中指向相同引用的 2 个对象必须具有相同的哈希码。

      所以,故事的寓意是,JVM 确保两个不同的对象永远不会相同,即使它们的哈希码相同。

      【讨论】:

      • 您查看您链接的那个错误了吗?它于 2008 年被报道,上一次关于它的活动是在 2 年前。如果真的坏了,早就修好了。
      • 我指的不是它的年龄。我指的是那个错误和对它的承认。我的意思是,这确实是一个错误。
      • bugs.sun.com/bugdatabase/view_bug.do?bug_id=5053846,您链接的错误是重复的。特别注意列出的最后一条评论。
      • 好吧,那条评论说它不正确,然后说应该删除重复的条目。他很困惑。
      • 他说这并没有违反规则或任何东西,但并不理想。
      【解决方案3】:

      正如我从 JVM 规范中了解到的那样,没有这样的限制可以防止常量池中的重复条目。 通常,生成类文件的编译器没有重复项。但即使类文件有重复项,也不应该影响其预期行为。

      你反编译的类文件是怎么创建的?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-22
        • 1970-01-01
        • 2023-03-22
        • 2019-07-25
        相关资源
        最近更新 更多