JVM学习笔记8——接口初始化规则与类加载器准备阶段和初始化阶段的重要意义分析
发布日期:2021-06-29 01:18:44 浏览次数:2 分类:技术文章

本文共 2842 字,大约阅读时间需要 9 分钟。

public class MyTest5 {    public static void main(String[] args){        System.out.println(MyChild5.b);    }}interface MyParent5 {    public static final int a = 5;}interface MyChild5 extends MyParent5 {    public static final int b = 6;}

程序会输出6,即使删掉MyParent5的class文件程序也能正常运行,(接口里的变量默认都是final的)说明

当一个接口在初始化时,并不要求其父接口都完成了初始化

MyChild5中的b改为

// 如果删掉MyParent5的class文件会报错public static final int b = new Random().nextInt(2);
public class MyTest5 {    public static void main(String[] args){        System.out.println(MyChild5.b);    }}interface MyParent5 {    public static final int a = new Random().nextInt(3); }interface MyChild5 extends MyParent5 {    public static final int b = 5;}

删掉MyParent5是可以正常执行

public class MyTest5 {    public static void main(String[] args){        System.out.println(MyChild5.b);    }}interface MyParent5 {    public static final int a = new Random().nextInt(3); }interface MyChild5 extends MyParent5 {    public static final int b = new Random().nextInt(4);}

删掉MyParent5会报错

只要在真正使用到父接口的时候(如引用接口中定义的常量时),才会初始化

public class MyTest6 {    public static void main(String[] args){        Singleton singleton = Singleton.getInstance();        System.out.println("counter1: " + Singleton.counter1);        System.out.println("counter2: " + Singleton.counter2);    }}class Singleton{    public static int counter1;    public static int counter2 = 0;    public static Singleton singleton = new Singleton();    private Singleton(){        counter1 ++;        counter2 ++;    }    public static Singleton getInstance(){        return singleton;    }}

 执行结果如下:

 将Singleton的counter2放在私有构造方法之后

class Singleton{    public static int counter1;    public static Singleton singleton = new Singleton();    private Singleton(){        counter1 ++;        counter2 ++; // 主动使用,在准备阶段赋上初值        // System.out.println("counter1: " + counter1);        // System.out.println("counter2: " + counter2);    }    // 代码移到这里输出就变成了0,执行到这里时相当于又手工赋值0    public static int counter2 = 0;     public static Singleton getInstance(){        return singleton;    }}

执行结果如下:

初始化的顺序是在代码里声明的位置从上到下,所以counter2在准备阶段是赋值为默认值0,然后在构造方法里加1,但是之后初始化又被重新赋值为指定的0

在私有构造方法中打印出来:

public class MyTest6 {    public static void main(String[] args){        Singleton singleton = Singleton.getInstance();        System.out.println("counter1: " + Singleton.counter1);        System.out.println("counter2: " + Singleton.counter2);    }}class Singleton{    public static int counter1;    public static Singleton singleton = new Singleton();    private Singleton(){        counter1 ++;        counter2 ++; // 主动使用,在准备阶段赋上初值,准备阶段的意义        System.out.println("counter1: " + counter1);        System.out.println("counter2: " + counter2);    }    // 代码移到这里输出就变成了0,执行到这里时相当于又手工赋值0    public static int counter2 = 0;    public static Singleton getInstance(){        return singleton;    }}

 

转载地址:https://blog.csdn.net/yshuoo/article/details/115728532 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:算法与数据结构基础课第一节笔记
下一篇:JVM学习笔记7——编译期常量与运行常量的区别及数组创建本质分析

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月28日 23时08分26秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章