在接口的常量池中包含 java.lang.Object 的目的是什么?

What's the purpose of including java.lang.Object in an interface's Constant Pool?

编译如下界面:

package test;

public interface MyInterface {
    public void foo();
}

并使用 javap -v -s test.MyInterface 检查编译代码显示如下(-s 打印成员签名):

  Compiled from "MyInterface.java"
public interface test.MyInterface
  SourceFile: "MyInterface.java"
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
Constant pool:
  #1 = Class              #7              //  test/MyInterface
  #2 = Class              #8              //  java/lang/Object
  #3 = Utf8               foo
  #4 = Utf8               ()V
  #5 = Utf8               SourceFile
  #6 = Utf8               MyInterface.java
  #7 = Utf8               test/MyInterface
  #8 = Utf8               java/lang/Object
{
  public abstract void foo();
    Signature: ()V
    flags: ACC_PUBLIC, ACC_ABSTRACT
}

我的问题是:为什么常量池里有java.lang.Object,明知道接口不是继承Object class?

此外,如果我将接口定义更改为:

public interface MyInterface extends Comparable<MyInterface> {
    public void foo();
}

和 运行 javap,我得到以下信息:

  Compiled from "MyInterface.java"
public interface test.MyInterface extends java.lang.Comparable<test.MyInterface>
  Signature: #7             // Ljava/lang/Object;Ljava/lang/Comparable<Ltest/MyInterface;>;
  SourceFile: "MyInterface.java"
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
  ...

在接口的签名Ljava/lang/Object;Ljava/lang/Comparable<Ltest/MyInterface;>;中包含java.lang.Object的具体目的是什么?

此外,如果我尝试使用工具(特别是 JBE)查看字节码,它会错误地显示 MyInterfacejava.lang.Object 作为 superclass 和 class 名称java.lang.Object保存在常量池中:

注:使用jdk1.7.0_75

其实Java里面的都是Object。在 Java 中,每个结构都是对象。

Class IS Object
Interface IS Object
Enum IS Object.

所以当你构建程序时 Object 自动打包。因为*.class可能在另一个JVM上使用。

@user43250937 在这种情况下是正确的 too

JVM Spec :

Compiled code to be executed by the Java Virtual Machine is represented using a hardware- and operating system-independent binary format, typically (but not necessarily) stored in a file, known as the class file format. The class file format precisely defines the representation of a class or interface, including details such as byte ordering that might be taken for granted in a platform-specific object file format

可能是这个link授予你更多的信息。

Java-bytecode-fundamentals-using-objects-and-calling-methods

看看

4:  invokeinterface #5,  1; //InterfaceMethod Job.execute:()Ljava/lang/Object;

JVM Specification

常量池中的 Object class 引用是 class 文件格式如何在 Java VM Specification.

中定义的结果

一个class文件由一个类文件结构组成:

ClassFile {
    u4             magic;  // The Famous 0xCAFEBABE
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    ...
}

关于 super_class,JVM 规范的这一部分与您的 MyInterface 接口相关:

super_class

For an interface, the value of the super_class item must always be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing the class Object.

所以本质上,java/lang/Object 常量只需要用有效值填充 super_class 项。 所有 Java 实例始终是基本 Object class 的实例,但这次真正的答案更多地与 JVM 的构建方式和特定的实现选择有关,而不是与语言本身有关.

此外,正如@Holger 所指出的,这一段也值得一提:

If the value of the super_class item is zero, then this class file must represent the class Object, the only class or interface without a direct superclass.