java中静态内部类的加载时机?

1,080 阅读5分钟

1.问题:

静态内部类的加载时机?他和外部类的加载有没有什么关系?

静态内部类的加载是在程序中调用静态内部类的时候加载的,和外部类的加载没有必然关系,但是在加载静态内部类的时候 发现外部类还没有加载,那么就会先加载外部类,加载完外部类之后,再加载静态内部类(初始化静态变量和静态代码块etc)。

如果在程序中单纯的使用 外部类,并不会触发静态内部类的加载

扩展:

①一个类内部有静态内部类和非静态内部类 , 静态内部类和非静态内部类一样,都是在被调用时才会被加载。不过在加载静态内部类的过程中如果没有加载外部类,也会加载外部类。
静态变量,静态方法,静态块等都是类级别的属性,而不是单纯的对象属性。他们在类第一次被使用时被加载 (记住,是一次使用,不一定是实例化)。我们可以简单得用 类名.变量 或者 类名.方法来调用它们。
 与调用没有被static 修饰过变量和方法不同的是:一般变量和方法是用当前对象的引用(即this)来调用的, 静态的方法和变量则不需要。从一个角度上来说,它们是共享给所有对象的,不是一个角度私有。 这点上,静态内部类也是一样的。
② 类的加载时机:(暂时的认知里是四种) new 一个类的时候,调用类内部的 静态变量,调用类的静态方法,调用类的 静态内部类。

测试代码如下:

package com.example.demo.entity.innerclass;
import lombok.SneakyThrows;


public class OuterClass {
    public static String OUTER_DATE = "外部类静态变量加载时间 "+System.currentTimeMillis();
static {
    System.out.println("外部类静态块加载时间:" + System.currentTimeMillis());
}
public OuterClass() {
    System.out.println("外部类构造函数时间:" + System.currentTimeMillis());
}

static class InnerStaticClass{
    public static String INNER_STATIC_DATE = "静态内部类静态变量加载时间 "+System.currentTimeMillis();
    static {
        System.out.println("静态内部类静态代码块加载时间:" + System.currentTimeMillis());
    }
}
class InnerClass {
    public String INNER_DATE = "";
    public InnerClass() {
        INNER_DATE = "非静态内部类构造器加载时间"+System.currentTimeMillis();
    }
}


@SneakyThrows
public static void main(String[] args) {
    //①main方法里没有任何代码运行结果
    //  外部类静态块加载时间:1614393999819

    //  说明:外部类静态变量的加载时间和外部类静态代码块的加载时间一样

    // ②
     //OuterClass outer = new OuterClass();
     //外部类静态块加载时间:1614394114095
     //外部类构造函数时间:1614394114095

    // 说明加载外部类的时候并没有加载静态内部类,外部类静态变量的加载时间和外部类静态代码块的加载时间一样


    // ③
    //        OuterClass outer = new OuterClass();
    //        Thread.sleep(10000L);
    //        System.out.println("外部类静态变量加载时间:" + outer.OUTER_DATE);

    //外部类静态块加载时间:1614394454245
    //外部类构造函数时间:1614394454245
    //外部类静态变量加载时间:外部类静态变量加载时间 1614394454245

    // 说明:加载外部类和加载静态内部类没有什么关系,外部类是程序调用外部类的的时候会加载



    //④
    //        OuterClass outer = new OuterClass();
    //        Thread.sleep(10000L);
    //        System.out.println("非静态内部类加载时间: "+outer.new InnerClass().INNER_DATE);
    //外部类静态块加载时间:1614394800484
    //外部类构造函数时间:1614394800484
    //非静态内部类加载时间: 非静态内部类构造器加载时间614394810501



    // ⑤(ps) 内部静态类可以直接用,不需要new
    //System.out.println("静态内部类加载时间____:"+InnerStaticClass.INNER_STATIC_DATE);
    //外部类静态块加载时间:1614395200427
    //静态内部类静态代码块加载时间:1614395200430
    //静态内部类加载时间____:静态内部类静态变量加载时间 1614395200430

    //说明:静态内部类的加载是代码中需要静态内部类的时候才加载,而不是和外部类一起加载的
    // 加载静态内部类之前,先把外部类的静态变量和静态代码块先执行完
    // 执行完外部类的代码后,再执行静态内部类的 静态变量和静态代码块
    // 静态内部类的 静态变量和静态代码块执行完后,然后执行业务代码(⑤ 中的打印语句)


    //⑥ 验证如果加载过了外部类,调用静态内部类不需要重新加载外部类
    //        OuterClass outer = new OuterClass();
    //        Thread.sleep(10000L);
    //        System.out.println("静态内部类加载时间___:"+InnerStaticClass.INNER_STATIC_DATE);
    // 外部类静态块加载时间:1614395065015
    //外部类构造函数时间:1614395065015
    //静态内部类静态代码块加载时间:1614395075029
    //静态内部类加载时间____:静态内部类静态变量加载时间 1614395075029

    // 说明:new  外部类的时候 。外部类的静态代码块和静态变量先执行,外部类构造函数后执行

    }
}

原文地址:blog.csdn.net/qq_38807606…