Java类对象的初始化顺序和类在什么时候会被加载

类对象初始化顺序及类加载时机

类对象初始化顺序

 分别在父类和子类中测试静态代码块、普通代码块、静态成员变量、构造器、静态内部类

  1. 代码块及变量测试
//
class Field {

    public static String baseFieldInit() {
        System.out.println("父类全局变量");
        return "";
    }

    public static String baseStaticFieldInit() {
        System.out.println("父类静态变量");
        return "";
    }


    public static String fieldInit() {
        System.out.println("子类全局变量");
        return "";
    }

    public static String staticFieldInit() {
        System.out.println("子类静态变量");
        return "";
    }
}


class Father {

    static {
        System.out.println("父类静态代码块1");
    }

    private static String staticValue = Field.baseStaticFieldInit();

    static {
        System.out.println("父类静态代码块2");
    }

    {
        System.out.println("父类构造代码块1");
    }

    private String value = Field.baseFieldInit();

    {
        System.out.println("父类构造代码块2");
    }

    Father() {
        System.out.println("父类构造器");
    }
}


public class Children extends Father {

    static {
        System.out.println("子类静态代码块1");
    }

    private static String staticValue = Field.staticFieldInit();

    static {
        System.out.println("子类静态代码块2");
    }

    {
        System.out.println("子类构造代码块1");
    }

    private String value = Field.fieldInit();

    {
        System.out.println("子类构造代码块2");
    }

    public Children() {
        System.out.println("子类无参构造器");
    }

    private static class House {
        private static Children houseChildren = new Children();
    }

    public static void main(String[] args) {
        //Children children = new Children();
        //System.out.println("Children:" + children);
        //System.out.println("********************************");
        //
        //Children children1 = new Children();
        //System.out.println("Children:" + children1);
        //System.out.println("********************************");

        Children house = House.houseChildren;
        System.out.println("ChildrenHouse:"+house);
        System.out.println("*******************************");
        Children chouse1 = House.houseChildren;
        System.out.println("ChildrenHouse:"+chouse1);
        System.out.println("*******************************");
    }
}
  1. 测试结果
父类静态代码块1
父类静态变量
父类静态代码块2
子类静态代码块1
子类静态变量
子类静态代码块2
父类构造代码块1
父类全局变量
父类构造代码块2
父类构造器
子类构造代码块1
子类全局变量
子类构造代码块2
子类无参构造器
Children:com.cmlx.design.classtest.Children@5f5a92bb
********************************
父类构造代码块1
父类全局变量
父类构造代码块2
父类构造器
子类构造代码块1
子类全局变量
子类构造代码块2
子类无参构造器
Children:com.cmlx.design.classtest.Children@6fdb1f78
********************************
  1. 测试静态内部类
父类静态代码块1
父类静态变量
父类静态代码块2
子类静态代码块1
子类静态变量
子类静态代码块2
父类构造代码块1
父类全局变量
父类构造代码块2
父类构造器
子类构造代码块1
子类全局变量
子类构造代码块2
子类无参构造器
ChildrenHouse:com.cmlx.design.classtest.Children@7440e464
*******************************
ChildrenHouse:com.cmlx.design.classtest.Children@7440e464
*******************************
  1. 总结
    (1) 静态代码块、静态成员变量只有第一次加载类时才会执行
    (2) 执行顺序为:父类静态代码块及父类静态成员变量(并列优先级)—>子类静态代码块及子类静态成员变量(并列优先级)—>父类普通代码块及父类成员变量—>父类构造器—>子类普通代码块及子类成员变量—>子类构造器
    (3) 静态内部类,只有在第一次调用的时候才会被初始化

java类在何时被加载

 IDEA配置VM options:-XX:+TraceClassLoading 监控类的加载
IDEA配置监控类的加载
 新建TestController测试加载时机

@RestController
public class ClassTestController {

    @RequestMapping("/newInstance")
    public String newInstance(){

        Father father = new Father();
        return "";
    }
    @RequestMapping("/newChildrenInstance")
    public String childrenInstance(){

        Children children = new Children();
        return "";
    }
    @RequestMapping("/staticField")
    public String staticField(){

        String staticValue = Children.staticValue;
        return "";
    }

    @RequestMapping("staticMethod")
    public String staticMethod(){

        String bed = Children.bed();
        return "";
    }

    @RequestMapping("classForName")
    public String classForName() throws Exception {

        Class.forName("com.zhixie.jvmclassload.demo.Children");
        return "";
    }

}

  1. 定义了main类,启动mian方法时该类会被加载
  2. 创建类的实例,即new对象的时候
    (1) 创建父类的实例
    (2) 创建子类的实例
  3. 访问类的静态方法
  4. 访问类的静态变量
  5. 反射Class.forName()

总结

  • java类在以上五种情况下会被加载
  • 在JVM生命周期中每个类如果存在,则不会重新加载
  • 在加载子类的时候会优先其父类
  • 类被加载的时候,其中的静态代码块、静态方法及静态变量也会被加载
  • 在初始化某个类时,如果这个类的静态代码块、静态方法或静态变量引用到了另一类,则这个类也会被加载
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值