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

时间:2015-06-01 14:03:08

标签: java interface jvm bytecode jvm-hotspot

编译以下界面:

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类?

此外,如果我将界面定义更改为:

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
  ...

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

此外,如果我尝试使用工具(特别是JBE)查看字节码,则会错误地显示MyInterface已将java.lang.Object作为超类,其中类名java.lang.Object保存在常量中池:

JBE screenshot

注意:使用jdk1.7.0_75

2 个答案:

答案 0 :(得分:8)

常量池中的Object类引用是在Java VM Specification中如何定义类文件格式的结果。

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

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

     

对于接口,super_class项的值必须始终为a   有效的索引进入constant_pool表。 constant_pool条目在   该索引必须是CONSTANT_Class_info结构,表示   班Object

基本上,仅需要java/lang/Object常量来填充super_class项的有效值。 所有Java实例始终是基本Object类的实例,但这一次真正的答案更多地与JVM的构建方式有关,而与具体的实现选择有关,而不是与语言本身有关。

另外,正如@Holger所说,这一段也值得一提:

  

如果super_class项的值为零,则为此类文件   必须代表类Object,这是唯一没有的类或接口   直接超类。

答案 1 :(得分:1)

实际上Java中的所有内容都是Object。在Java中,每个构造都是对象。

Class IS Object
Interface IS Object
Enum IS Object.

因此,当您自动构建程序Object时。因为*.class可能在另一个JVM上使用。

@ user43250937在这种情况下正确too

JVM Spec :
  

由Java虚拟机执行的编译代码使用独立于硬件和操作系统的二进制格式表示,通常(但不一定)存储在文件中,称为类文件格式。类文件格式精确定义类或接口的表示,包括可能以特定于平台的目标文件格式认为是理所当然的字节排序等详细信息

可以将此链接授予您的更多信息。

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

看看

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

JVM Specification