zoukankan      html  css  js  c++  java
  • Java类初始化顺序

    只恨上课的时候没有认真听讲,在网易笔试的过程中碰到了Java类初始化顺序的题目。
    马上重新学习,不敢怠慢,写下此文


    无继承的类的初始化过程

    在Java中类的初始化优先级是: 静态 > 实例 > 构造器

    静态:包括静态变量,静态初始化块,也就是关键字 static 修饰部分的代码,静态部分的初始化,按照类内的定义顺序执行初始化。
    实例:和C++不同,Java的实例变量(instance variable)支持类内初始化,这里的“实例”,指的就是实例变量、或实例初始化块。执行顺序也是按照类内定义的顺序进行初始化
    构造器:就是构造方法,这个就不用多说

    看下面的实验代码

    /**
     * @author Lisupy
     * @email zhong550413470@gmail.com
     * 类初始化测试
     * */
    public class InitialOrderTest {
    
        // instance variable
        private String val = "instance val";
    
        // instance initial block
        {
            System.out.println(val);
            System.out.println("Executing in instance initial block");
        }
    
        // static variable
        private static String staticVal = "static val";
    
        // static initial block
        static {
            System.out.println(staticVal);
            System.out.println("Executing in static block");
        }
    
        // Constructor
        public InitialOrderTest(){
            System.out.println("Executing in Constructor");
        }
    
        public static void main(String[] args){
            new InitialOrderTest();
            new InitialOrderTest();
        }
    }
    

    这段代码运行的结果为

    static val
    Executing in static block
    instance val
    Executing in instance initial block
    Executing in Constructor
    instance val
    Executing in instance initial block
    Executing in Constructor

    静态初始化部分在类被加载的时候先执行且执行一次,实例初始化部分在每次创建新的实例对象时先运行,再运行构造方法
    上面的代码中,由于静态初始化代码的静态块依赖于静态变量,所以二者的顺序不能替换,替换后会出现编译错误 java: illegal forward reference, 这也证明了代码的执行顺序是按照类内定义的顺序执行的。


    有继承关系的类的初始化过程

    对于有继承关系的类的初始化情况,比上面的复杂,所以也经常列为考点。但是再复杂也万变不离其宗, 就是优先级按照 "静态">"实例">"构造器", 但是有稍微一点不同,看下面的代码

    /**
     * 代码转于http://www.cnblogs.com/jackyrong/archive/2008/08/12/1266161.html
     */
    class Parent {   
        // 静态变量   
        public static String p_StaticField = "父类--静态变量";   
        // 变量   
        public String p_Field = "父类--变量";   
      
        // 静态初始化块   
        static {   
            System.out.println(p_StaticField);   
            System.out.println("父类--静态初始化块");   
        }   
      
        // 初始化块   
        {   
            System.out.println(p_Field);   
            System.out.println("父类--初始化块");   
        }   
      
        // 构造器   
        public Parent() {   
            System.out.println("父类--构造器");   
        }   
    }   
      
    public class SubClass extends Parent {   
        // 静态变量   
        public static String s_StaticField = "子类--静态变量";   
        // 变量   
        public String s_Field = "子类--变量";   
        // 静态初始化块   
        static {   
            System.out.println(s_StaticField);   
            System.out.println("子类--静态初始化块");   
        }   
        // 初始化块   
        {   
            System.out.println(s_Field);   
            System.out.println("子类--初始化块");   
        }   
      
        // 构造器   
        public SubClass() {   
            System.out.println("子类--构造器");   
        }   
      
        // 程序入口   
        public static void main(String[] args) {   
            new SubClass();   
        }   
    }  
    
    

    运行结果如下

    父类--静态变量
    父类--静态初始化块
    子类--静态变量
    子类--静态初始化块
    父类--变量
    父类--初始化块
    父类--构造器
    子类--变量
    子类--初始化块
    子类--构造器

    对于这个运行结果,说一说我的见解:
    总体来说,初始化过程满足上面所说的优先级 "静态">"实例">"构造器",但是要添加一个另外的条件"父类">"子类"
    就上述的代码来说,在类加载的过程中就必须满足 "父类" > "子类",所以父类的静态代码 优先于 子类的静态代码,符合上述运行结果
    实例初始化代码是在创建类的过程中运行的,由于子类的初始化可能会依赖到父类的初始化的成员,所以先运行父类的实例初始化块和构造方法,再运行子类的初始化块和构造方法


    上述的内容均属于我自己的理解,有可能和实际有所区别,如果各位看官发现任何错误,请指出来,我会听取您的意见改善这篇博文。

  • 相关阅读:
    朗志轻量级项目管理解决方案-RBAC角色权限模块介绍
    关于业务规则层、业务实体层、业务外观层、模型层的作用很不清楚,殷切期望解答
    已有类实例,现在想拥有另一个相同状态的实例,除了反序列化还有别的办法吗?
    签名工具
    请教一个winform程序设计上的问题
    在使用WeifenLuo Suite时遇到的问题,自己记录一下,备忘
    解读C#正则表达式
    [导入]jbuilder 2006开发struts+sqlserver2K准备工作
    如何用设计模式变相实现类的多继承?
    WriteXmlSchema(xsdFileName)和GetXmlSchema()输出的内容的差异
  • 原文地址:https://www.cnblogs.com/pluviophile/p/7513790.html
Copyright © 2011-2022 走看看