编译以下界面:
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
保存在常量中池:
注意:使用jdk1.7.0_75
答案 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;