实验是检验真理的唯一标准。
下面我们通过实验来看看Java内部类的继承关系和他们的默认构造方法是怎样的。
实验1
public class A extends B{
public static void main(String[] args) {
Class superClazz = A.class.getSuperclass();
System.out.println("A的父类:" + superClazz.getName());
System.out.println("A的祖先类:" + superClazz.getSuperclass().getName());
}
}
//输出
//A的父类:B
//A的祖先类:java.lang.Object
结论:所有外部类的祖先类都是Object
实验2:内部类的父类
public class A{
public static void main(String[] args) {
Class superClazz = C.class.getSuperclass();
System.out.println("C的父类:" + superClazz.getName());
}
class C {
int c;
}
}
//输出:
//C的父类:java.lang.Object
public class A{
public static void main(String[] args) {
Class superClazz = C.class.getSuperclass();
System.out.println("C的父类:" + superClazz.getName());
}
static class C {
int c;
}
}
//输出:
//C的父类:java.lang.Object
public static void main(String[] args) {
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
}
};
Class superClazz = actionListener.getClass().getSuperclass();
System.out.println("匿名内部类的名称:" + actionListener.getClass().getName());
System.out.println("匿名内部类的父类:" + superClazz.getName());
}
//输出:
//匿名内部类的名称:A$1
//匿名内部类的父类:java.lang.Object
结论:成员/静态/匿名内部类的父类是Object
实验3:内部类的构造方法
public class A{
public static void main(String[] args) {
C c = new C();
c.c = 3;
}
static class C {
int c;
}
}
通过javap -c A$C.class查看字节码
Compiled from "A.java"
class A$C {
int c;
A$C();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
}
对于成员内部类:
public class A{
public static void main(String[] args) {
new A().test();
}
void test() {
A.C c = new A.C();
}
class C {
int c;
}
}
Compiled from "A.java"
class A$C {
int c;
final A this$0;
A$C(A);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:LA;
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V
9: return
}
结论:
- 静态内部类有一个默认的无参构造方法
- 成员内部类有一个默认的带一个参数的构造方法,这个参数是外部类的实例