zoukankan      html  css  js  c++  java
  • 访问类的静态属性与类的初始化

    访问类的静态属性与类的加载


    1. 访问类的静态变量

    现有SuperClass类,其源码如下:

    public class SuperClass {
        public static String staticVariable = "staticVariable";
        public static final String STATIC_CONSTANT = "STATIC_CONSTANT";
    
        static {
            System.out.println("SuperClass is loading.");
        }
    }
    

    现有一段代码,访问SuperClass类中的静态变量staticVariable:

    public class MainClass {
        static {
            System.out.println("MainClass is loading.");
        }
    
        public static void main(String[] args) {
            // 访问类的静态变量
            System.out.println(SuperClass.staticVariable);
        }
    }
    

    上述代码执行后,控制台输出为:

    MainClass is loading.
    SuperClass is loading.
    staticVariable
    

    从代码的执行结果看,对类的静态变量的引用将会触发类的初始化过程

    2. 访问类的静态常量

    现有一段代码,访问SuperClass类中的静态常量STATIC_CONSTANT:

    public class MainClass {
        static {
            System.out.println("MainClass is loading.");
        }
    
        public static void main(String[] args) {
            // 访问类的静态常量
            System.out.println(SuperClass.STATIC_CONSTANT);
        }
    }
    

    上述代码执行后,控制台输出为:

    MainClass is loading.
    STATIC_CONSTANT
    

    从代码的指定结果看,对类的静态常量的引用不会触发类的初始化过程

    从源码看,MainClass类直接引用了SuperClass类的静态常量,但经过编译阶段的“常量传播优化”后,该静态常量的值“STATIC_CONSTANT”已经被存储到了MainClass类自己的常量池中,MainClass类对该静态常量的引用也被修改成了对自身常量池的引用。换句话说,经过编译后,MainClass类与SuperClass类已经不存在任何联系了,MainClass类的字节码文件中,不存在SuperClass类的符号引用入口。

    3. 访问父类的静态变量

    现有SuperClass类的子类SubClass,其源码如下:

    public class SubClass extends SuperClass{
        static {
            System.out.println("SubClass is loading.");
        }
    }
    

    现有一段代码,通过SubClass类调用SuperClass类的静态变量:

    public class MainClass {
        static {
            System.out.println("MainClass is loading.");
        }
    
        public static void main(String[] args) {
            // 调用父类的静态变量
            System.out.println(SubClass.staticVariable);
        }
    }
    

    上述代码执行后,控制台输出为:

    MainClass is loading.
    SuperClass is loading.
    staticVariable
    

    从上述代码的执行结果看,通过子类引用父类的静态变量,并没有触发子类的初始化过程。其实,Java虚拟机规范中并未明确规定,对父类静态变量的引用是否要触发子类的初始化,这是由具体的虚拟机实现来决定的。

    在上述代码的基础上,添加语句输出代码运行时的虚拟机环境信息:

    public class MainClass {
        static {
            System.out.println("MainClass is loading.");
        }
    
        public static void main(String[] args) {
            System.out.println(SubClass.staticVariable);
            System.out.println("Java 虚拟机实现名称:" + System.getProperty("java.vm.name"));
            System.out.println("Java 虚拟机实现版本:" + System.getProperty("java.vm.version"));
        }
    }
    
    MainClass is loading.
    SuperClass is loading.
    staticVariable
    Java 虚拟机实现名称:Java HotSpot(TM) 64-Bit Server VM
    Java 虚拟机实现版本:25.171-b11
    

    从控制台输出可以看出,当前我使用的是HotSpot虚拟机。

    4. 访问父类的静态常量

    现有一段代码,通过SubClass类访问父类SuperClass类的静态常量:

    public class MainClass {
        static {
            System.out.println("MainClass is loading.");
        }
    
        public static void main(String[] args) {
            System.out.println(SubClass.STATIC_CONSTANT);
        }
    }
    

    代码执行后的控制台输出:

    MainClass is loading.
    STATIC_CONSTANT
    

    从上述代码的执行结果,与上文“ 2. 访问类的静态常量 ”处代码的执行结果相同。

  • 相关阅读:
    SpringBoot项目maven 打包时跳过测试
    scss 学习笔记
    万事都源于一个字:缘
    H To begin or not to begin 题解(思维)
    条件 题解(bitset优化floyd)
    Dima and Salad 题解(01背包变形)
    P1052 [NOIP2005 提高组] 过河 题解(dp+数论优化)
    A Simple Math Problem 题解(数论)
    威佐夫博弈
    P3951 [NOIP2017 提高组] 小凯的疑惑 题解(数论/结论题)
  • 原文地址:https://www.cnblogs.com/XiaoZhengYu/p/13190439.html
Copyright © 2011-2022 走看看