在类中定义一个新的类,该类即为内部类。内部类具有代码隐藏、与外部类通信等特点。现在讨论非静态内部类、外部类、静态内部类的加载顺序。
1 静态内部类、外部类加载
public class OuterClass {
public static long OUT_STATIC_TIME = System.currentTimeMillis();
static { System.out.println("static method load :" + System.currentTimeMillis()); }
OuterClass() {System.out.println("OuterClass construct :" + System.currentTimeMillis());}
static class StaticInnerClass {
public static long In_STATIC_TIME = System.currentTimeMillis();
static { System.out.println("inner static method load : " + System.currentTimeMillis()); }
StaticInnerClass() { System.out.println("StaticInnerClass construct : " + System.currentTimeMillis()); }
}
public static void main(String[] args) {
System.out.println("main function load : " + System.currentTimeMillis());
OuterClass outerClass = new OuterClass();
System.out.println("static variable in OuterClass : " + outerClass.OUT_STATIC_TIME);
}
}
/* Output:
static method load :1582426731064
main function load : 1582426731064
OuterClass construct :1582426731064
static variable in OuterClass : 1582426731064
*/
对比main函数、代码输出得知, 调用外部类静态变量OUT_STATIC_TIME时,加载顺序如下:
Step1:加载外部类的静态代码块
Step2:进入主函数
Step3:调用外部类构造函数OutClass(),进行外部类的实例化
注意到,此时内部静态类StaticInnerClass并没有加载,更没有实例化。
对上述代码main函数稍作改动,注释掉外部类OuterClass的实例化,通过外部类OuterClass直接调用外部类静态变量OUT_STATIC_TIME。代码及输出如下:
public static void main(String[] args) {
System.out.println("main function load : " + System.currentTimeMillis());
//OuterClass outerClass = new OuterClass();
System.out.println("static variable in OuterClass : " + OuterClass.OUT_STATIC_TIME);
}
/* Output:
static method load :1582427779675
main function load : 1582427779675
static variable in OuterClass : 1582427779675
*/
可以看到:外部类、内部静态类都没有实例化,加载静态代码块,进入主函数,调用外部类的静态变量。
2 非静态内部类的加载顺序
public static void main(String[] args) {
System.out.println("main function load : " + System.currentTimeMillis());
OuterClass outerClass = new OuterClass();
OuterClass.NonStaticInnerClass nonStaticInnerClass = outerClass.new NonStaticInnerClass();
System.out.println("variable in NonStaticInnerClass" + nonStaticInnerClass.In_NONSTATIC_TIME);
}
/* Output:
static method load :1582435735675
main function load : 1582435735675
OuterClass construct :1582435735675
NonStaticInnerClass construct : 1582435735691
variable in NonStaticInnerClass1582435735691
*/
对比发现:
第一:此处没有调用静态内部类变量/方法,故没有加载静态内部类;
第二:非静态类的实例化需要依托外部类。首先实例化外部类,再实例化内部类。