本文最后更新于:星期四, 六月 18日 2020, 9:01 上午

public class Main {
    static {
        System.out.println("加载外部类");

    }
    public Main() {
        System.out.println("外部类构造方法");
    }

    public void newInnerClassInstance() {
        InnerClass innerClass = new InnerClass();
    }
    public void loadStaticInnerClass(){
        StaticInnerClass.i=100;
    }

    public static void main(String[] args) throws Throwable {
        Main main = new Main();
        main.newInnerClassInstance();
        main.loadStaticInnerClass();
    }
    private class InnerClass {
        {
            System.out.println("加载内部类");
        }
    }
    static class StaticInnerClass {
        static int i=0;
        static {
            System.out.println("加载静态内部类");
        }
    }
}
//print:
/**
 * 加载外部类
 * 外部类构造方法
 * 加载内部类
 * 加载静态内部类
 */

解释打印的原因:
加载外部类: 当虚拟机启动时,我们指定的main方法的main类,由虚拟机来加载,因此肯定会初始化这个类。
外部类构造方法:由语句Main main=new Main();引起
加载内部类:由语句main.newInnerClassInstance()#InnerClass innerClass = new InnerClass();引起,由于内部类没有static块和纯static变量(常量的调用无法引起类加载),所以只能通过new或者反射来引起初始化,这里用new语句创建对象来初始化内部类,并用普通实例代码块来表示初始化了类(无法使用static块)。
加载静态内部类:和普通类加载就没区别,本来静态内部类就和外部类没有太大关联,和普通的类十分接近。由于加载内部类已经用了new语句来初始化类了,这里就采用调用了静态字段的方法来使类初始化。


此外,为什么非静态内部类不能有static字段、static方法、static块?

  • 首先,内部类对象必须天然地持有唯一的对外部类对象的引用,一个外部类对象可以有许多内部类对象的引用,但是一个内部类有且必须有唯一一个对外部类对象的引用。
  • 暂时没有找到比较靠谱的解释,或许从虚拟机的角度来看会比较容易理解,待定…

Java     

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

线程生命周期和同步监视器是什么 上一篇
java变量初始化时的赋值 下一篇