java.lang.Object の親クラスについて
java.lang.Object クラスは全てのクラスに関して最も親のクラスであるが、その親クラスはどうなっているのだろうかと思い、クラスファイルを javap -v -p Object
でデコンパイルしてみた。
結果は次の通り(抜粋):
public class java.lang.Object
minor version: 0
major version: 61
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #8 // java/lang/Object
super_class: #0
interfaces: 0, fields: 0, methods: 12, attributes: 1
Constant pool:
#1 = Class #2 // java/lang/StringBuilder
#2 = Utf8 java/lang/StringBuilder
#3 = Methodref #1.#4 // java/lang/StringBuilder."<init>":()V
#4 = NameAndType #5:#6 // "<init>":()V
index が 1 スタートである定数プールに対して、super_class
フィールドには #0
が指定されている。無論定数プールにはこんなインデックスは存在しない。
Chapter 4. The class File Format | The Java® Virtual Machine Specification Java SE 17 Edition によれば、クラスファイルの構造は次のような構造をしている。
ClassFile {
u4 magic;
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;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
なんだ、仕様書に書いてあった。
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.
Object クラスに限り super_class
フィールドは 0
となるらしい。
結論として java.lang.Object
には親クラスなど存在しない!というのが正しそうだ。
ちなみに適当なクラスを作って同様にデコンパイルしてみると次のような結果が得られる。super_class
は定数プールの Class
を指すようになる。
これらを考慮してみると、さっきは定数プールを「index が 1 から始まるもの」だとしたが、実は「0 スタートだが 0 番は予約されているので、普段は 1 スタートである」という解釈の方が納得できるような気がする。
class Variables
minor version: 0
major version: 61
flags: (0x0020) ACC_SUPER
this_class: #12 // Variables
super_class: #2 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
#1 = Methodref #2.#3 // java/lang/Object."<init>":()V
#2 = Class #4 // java/lang/Object