• 3.JVM的接口初始化规则与类加载器准备阶段和初始化阶段的重要意义分析


    一.回顾类的运行期常量

    • 类的静态常量:public static final

      • 当MyTest类的方法调用MyChild中运行期常量时就需要初始化MyChild类及其所有父类

      • 当MyTest类的方法调用MyChild中编译期常量时不需要初始化MyChild类及其所有父类,由于编译期常量被放在MyTest类的常量池中了

    • 类的静态变量:public static

      • 当MyTest类的方法中调用子类名.父类静态变量,会初始化父类,不会初始化子类

      • 当MyTest类的方法中调用子类名.子类静态变量,会初始化父类和子类

    二.分析接口

    • 由于接口中的属性默认为public static final,则默认为静态常量。则和类的静态常量的运行期和编译期一模一样。

    三.例题分析

    结论:静态变量初始化顺序从上到下依次进行

    (1)案例一

     1 public class MyTest5 {
     2 
     3     public static void main(String[] args) {
     4         Singleton singleton = Singleton.getInstance();
     5 
     6         System.out.println("counter1: "+Singleton.counter1);
     7         System.out.println("counter2: "+Singleton.counter2);
     8     }
     9 }
    10 
    11 class Singleton {
    12     public static int counter1;
    13 
    14     public static int counter2 = 0;
    15 
    16     private static Singleton singleton = new Singleton();
    17 
    18     private Singleton(){
    19         counter1++;
    20         counter2++;
    21     }
    22 
    23     public static Singleton getInstance(){
    24         return singleton;
    25     }
    26 }
    27 
    28 /*
    29 * 输出:
    30 * counter1: 1
    31 * counter2: 1
    32 * */

    分析初始化过程:

    1. 调用getInstance方法返回singleton,此时调用初始化过程

    2. 准备阶段:代码从上往下先进行静态变量赋默认值,counter1 = 0,counter2 = 0,singleton = null

    3. 初始化阶段:counter2 = 0,singletton调用私有构造函数得counter1 = 1,counter2 = 1

    4. 结果为counter1 = 1,counter2 = 1

    (2)案例二

    案例二只是将案例一中的 public static int counter2 = 0; 位置改变了。

     1 public class MyTest5 {
     2 
     3     public static void main(String[] args) {
     4         Singleton singleton = Singleton.getInstance();
     5 
     6         System.out.println("counter1: "+Singleton.counter1);
     7         System.out.println("counter2: "+Singleton.counter2);
     8     }
     9 }
    10 
    11 class Singleton {
    12     public static int counter1;
    13 
    14     private static Singleton singleton = new Singleton();
    15 
    16     private Singleton(){
    17         counter1++;
    18         counter2++;
    19     }
    20 
    21     public static int counter2 = 0;
    22 
    23     public static Singleton getInstance(){
    24         return singleton;
    25     }
    26 }
    27 
    28 /*
    29 * 输出:
    30 * counter1: 1
    31 * counter2: 0
    32 * */

    分析初始化过程:

    1. 调用getInstance方法返回singleton,此时调用初始化过程

    2. 准备阶段:代码从上往下先进行静态变量赋默认值,counter1 = 0,singleton = null,counter2 = 0

    3. 初始化阶段:singletton调用私有构造函数得counter1 = 1,counter2 = 1,再counter2 = 0

    4. 结果为counter1 = 1,counter2 = 0

  • 相关阅读:
    URL中 # (hash)的含义
    哈弗曼树的理解和实现(Java)
    树、森林和二叉树的转换
    后序线索化二叉树(Java版)
    线索二叉树的理解和实现(Java)
    彻底理解线索二叉树
    链式二叉树的实现(Java)
    数和二叉树的基本概念和类型
    数据结构:广义表的实现(Java)
    正则表达式要转义的字符集
  • 原文地址:https://www.cnblogs.com/zhihaospace/p/12293193.html
Copyright © 2020-2023  润新知