初始化-主动使用实例分析

根据上一节的理论我们知道,每个类的接口被Java程序“首次主动使用”时才初始化,这一节我们就通过具体的实例来验证一下

  1. 创建类的实例
public class MyTest1 {
    public static void main(String[] args) {
        new MyParent1();
    }
}
class MyParent1 {
    public static String str = "hello world";

    static {
        System.out.println("MyParent static block");
    }
}

运行程序,输出:

MyParent static block

类的静态代码块被执行了,说明类进行了初始化

  1. 访问某个类或接口的静态变量,或者对该静态变量赋值
public class MyTest1 {
    public static void main(String[] args) {
        System.out.println(MyParent1.str);
    }
}
class MyParent1 {
    public static String str = "hello world";

    static {
        System.out.println("MyParent static block");
    }
}

运行程序,输出:

MyParent static block
hello world
  1. 调用类的静态方法
public class MyTest1 {
    public static void main(String[] args) {
        MyParent1.print();
    }
}
class MyParent1 {
    public static String str = "hello world";

    public static void print(){
        System.out.println(str);
    }

    static {
        System.out.println("MyParent static block");
    }
}

运行程序,输出:

MyParent static block
hello world
  1. 反射
public class MyTest1 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("com.shengsiyuan.jvm.classloader.MyParent1");
    }
}
class MyParent1 {
    public static String str = "hello world";

    static {
        System.out.println("MyParent static block");
    }
}

运行程序,输出:

MyParent static block
  1. 初始化一个类的子类
public class MyTest1 {
    public static void main(String[] args) throws ClassNotFoundException {
        new MyChild1();
    }
}
class MyParent1 {
    public static String str = "hello world";

    static {
        System.out.println("MyParent static block");
    }
}

class MyChild1 extends MyParent1 {
    public static String str2 = "welcome";

    static {
        System.out.println("MyChild1 static block");
    }
}

运行程序,输出:

MyParent static block
MyChild1 static block
  1. Java虚拟机启动时被表明为启动类的类
public class MyTest1 {
    static {
        System.out.println("MyTest1 static block");
    }
    public static void main(String[] args) throws ClassNotFoundException {
        
    }
}

运行程序,输出:

MyTest1 static block

非主动使用注意点

以上实例都是对主动使用的验证,我们来看一下下面这个程序

public class MyTest1 {
  public static void main(String[] args) throws ClassNotFoundException {
      System.out.println(MyChild1.str);
  }
}
class MyParent1 {
  public static String str = "hello world";

  static {
      System.out.println("MyParent static block");
  }
}

class MyChild1 extends MyParent1 {
  static {
      System.out.println("MyChild1 static block");
  }
}

运行程序,输出:

MyParent static block
hello world

我们可以看到,MyChild1 static block并没有打印出来,这里我们调用MyChild1.str明明是对类的静态变量的访问,但是MyChild1却没有被初始化,所以这里要注意的一点就是:

对于静态字段来说,只有直接定义了该字段的类才会被初始化


参考资料:
圣思园JVM课程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,026评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,780评论 18 399
  • 6.6日咖啡冥想 我的目标是带领C2月业绩上百万 所以我的咖啡冥想内容是: 1,把自己上个月带团队的过程中的经验进...
    艳敏姐阅读 327评论 0 0
  • 分享一下我的所见所闻,再加上我的所感。 我发现我们身边的朋友们对于外国人都有一种神秘感。我觉得其实都是人类,都有人...
    长春藤0805阅读 359评论 0 1
  • 无论受了什么伤 都请在那一天内结束悲伤 你明白的 这个城市的车水马龙 从来都不会在乎你昨天的泣不成声
    无言以若阅读 276评论 0 0