未在字节码中扩展 java.lang.Object。那么为什么编译器不在更新版本的 java 中添加它呢?

Not getting extends java.lang.Object in bytecode. so why compiler is not adding it in newer version of java?

我有如下简单的代码

package prashant;
public class CheckObject {
}

我使用了 javap -c CheckObject 并得到了以下字节码:

 Compiled from "CheckObject.java"
 public class prashant.CheckObject {
 public prashant.CheckObject();
 Code:
   0: aload_0       
   1: invokespecial #8                  // Method java/lang/Object."<init>":()V
   4: return        
  }

与旧版本的 Java 一样,隐式编译器在字节码中添加 extends Object 为:

public class prashant.CheckObject extends java.lang.Object

所以我有两个关于 extends Object 的问题:

1) 是否因为性能受到影响而未添加?

2) 它在哪个 java 版本中更改了?

java 用于编译此代码的版本是 1.6.0_45.

您打印的是反汇编,而不是原始字节码,并且反汇编被设计为便于人类阅读。没有声明超类的对象必须 extends Object(如构造函数的注释所示),因此列出它是多余的。

撇开编译器是否真的改变了1的问题……改变几乎是无关紧要的。

  • 如果没有显式调用Object构造函数,它会在class文件中保存少量space。您保存了 4 个字节的字节码,以及(我认为)构造函数签名的一个常量池条目。

  • 当字节码仍在被解释时,执行显式构造函数调用与隐式构造函数调用的执行速度可能略有不同。但差异可以忽略不计,我不准备预测哪个会更快。

一旦代码被 JIT 编译,我有信心地预测代码的两个不同版本之间将/将没有性能差异。我预测 JIT 编译器将以同等速度生成代码。 (任何对此的 JIT 编译器优化早就已经实现,因为链接到 Object<init> 几乎每次构造对象时都会应用。)


在源代码级别,普遍认为构造函数中的 super() 调用对性能的影响为零,无论 superclass 是什么。同样,如果您显式地写或不写 extends Object.

,则性能差异为零

任何注释的唯一区别在于可读性。这纯粹是代码风格问题。


1 - 您没有以任何方式提供可靠的证据。看评论。

首先,每个 class 必须有一个 superclass(java/lang/Object 本身除外)。对此没有任何改变。

问题是您使用的 javap 是为 Java 程序员设计的,因此往往会隐藏 class 文件格式的不方便细节,使输出看起来更Java 喜欢。如果您想查看 class 文件中的真实内容,您需要使用不同的反汇编程序 (such as the Krakatau disassembler)。

据推测,旧版本的 javap 没有隐藏 Object superclasses 但后来更新为隐藏它们。您的 class 文件没有改变,只有您的反汇编器改变了。