Java类初始化过程

学习java,对于java类的初始化过程很迷惑,不是很了解其过程,所以在网上和书籍上整理了一下。
摘自:解析 Java 类和对象的初始化过程


类初始化
类”初始化”阶段,它是一个类或接口被首次使用的前阶段中的最后一项工作,本阶段负责为类变量赋予正确的初始值。
Java 编译器把所有的类变量初始化语句和类型的静态初始化器通通收集到 方法内,该方法只能被 Jvm 调用,专门承担初始化工作。
除接口以外,初始化一个类之前必须保证其直接超类已被初始化,并且该初始化过程是由 Jvm 保证线程安全的。另外,并非所有的类都会拥有一个 () 方法,在以下条件中该类不会拥有 () 方法:
1.1、该类既没有声明任何类变量,也没有静态初始化语句;
1.2、该类声明了类变量,但没有明确使用类变量初始化语句或静态初始化语句初始化;
1.3、该类仅包含静态 final 变量的类变量初始化语句,并且类变量初始化语句是编译时常量表达式。


对象初始化
在类被装载、连接和初始化,这个类就随时都可能使用了。对象实例化和初始化是就是对象生命的起始阶段的活动,在这里我们主要讨论对象的初始化工作的相关特点。
Java 编译器在编译每个类时都会为该类至少生成一个实例初始化方法–即 “()” 方法。此方法与源代码中的每个构造方法相对应,如果类没有明确地声明任何构造方法,编译器则为该类生成一个默认的无参构造方法,这个默认的构造器仅仅调用父类的无参构造器,与此同时也会生成一个与默认构造方法对应的 “()” 方法.
通常来说,() 方法内包括的代码内容大概为:调用另一个 () 方法;对实例变量初始化;与其对应的构造方法内的代码。
如果构造方法是明确地从调用同一个类中的另一个构造方法开始,那它对应的 () 方法体内包括的内容为:一个对本类的 () 方法的调用;对应用构造方法内的所有字节码。
如果构造方法不是通过调用自身类的其它构造方法开始,并且该对象不是 Object 对象,那 () 法内则包括的内容为:一个对父类 () 方法的调用;对实例变量初始化方法的字节码;最后是对应构造子的方法体字节码。
如果这个类是 Object,那么它的 () 方法则不包括对父类 () 方法的调用。


类的初始化时机
本文到目前为止,我们已经大概有了解到了类生命周期中都经历了哪些阶段,但这个类的生命周期的开始阶段–类装载又是在什么时候被触发呢?类又是何时被初始化的呢?让我们带着这三个疑问继续去寻找答案。
Java 虚拟机规范为类的初始化时机做了严格定义:”initialize on first active use”–” 在首次主动使用时初始化”。这个规则直接影响着类装载、连接和初始化类的机制–因为在类型被初始化之前它必须已经被连接,然而在连接之前又必须保证它已经被装载了。
在与初始化时机相关的类装载时机问题上,Java 虚拟机规范并没有对其做严格的定义,这就使得 JVM 在实现上可以根据自己的特点提供采用不同的装载策略。我们可以思考一下 Jboss AOP 框架的实现原理,它就是在对你的 class 文件装载环节做了手脚–插入了 AOP 的相关拦截字节码,这使得它可以对程序员做到完全透明化,哪怕你用 new 操作符创建出的对象实例也一样能被 AOP 框架拦截–与之相对应的 Spring AOP,你必须通过他的 BeanFactory 获得被 AOP 代理过的受管对象,当然 Jboss AOP 的缺点也很明显–他是和 JBOSS 服务器绑定很紧密的,你不能很轻松的移植到其它服务器上。嗯~……,说到这里有些跑题了,要知道 AOP 实现策略足可以写一本厚厚的书了,嘿嘿,就此打住。
说了这么多,类的初始化时机就是在”在首次主动使用时”,那么,哪些情形下才符合首次主动使用的要求呢?
首次主动使用的情形:
创建某个类的新实例时–new、反射、克隆或反序列化;
调用某个类的静态方法时;
使用某个类或接口的静态字段或对该字段赋值时(final字段除外);
调用Java的某些反射方法时
初始化某个类的子类时
在虚拟机启动时某个含有main()方法的那个启动类。
除了以上几种情形以外,所有其它使用JAVA类型的方式都是被动使用的,他们不会导致类的初始化。

不存在继承关系的java类初始化:

 /**
 * @category java类初始化过程(无继承情况),其初始化的成员包含:静态变量、静态初始化块、变量、初始化块、构造方法。
 *           其初始化的先后顺序(静态变量,静态初始化块) > (变量,初始化块) > 构造方法。
 * @author ProgrammerMonkey
 */
public class JavaForClassInitialize {

    /**静态变量*/
    public static String staticVariable = "静态变量";
    /**变量*/
    public String variable = "变量";
    /**静态初始化块*/
    static
    {
        System.out.println(staticVariable);
        System.out.println("静态初始化块");
    }
    /**初始化块*/
    {
        System.out.println(variable);
        System.out.println("初始化块");
    }
    /**构造方法*/
    public JavaForClassInitialize() {
        System.out.println("构造方法");
    }
    public static void main(String[] args) {
        JavaForClassInitialize javaForClassInitialize = new JavaForClassInitialize();
    }
}

执行代码,其输出的结果为:

静态变量
静态初始化块
变量
初始化块
构造方法

存在继承关系的java类初始化:

/**
 * @category java类初始化过程(存在继承情况),其初始化的成员包含:静态变量、静态初始化块、变量、初始化块、构造方法。
 *           其初始化的先后顺序(静态变量,静态初始化块) > (变量,初始化块) > 构造方法。
 * @author ProgrammerMonkey
 */
public class JavaForClassExtendsInitialize extends Partner {
    /**子类-静态变量*/
    public static String staticVariable = "子类-静态变量";
    /**子类-变量*/
    public String variable = "子类-变量";
    /**子类-静态初始化块*/
    static {
        System.out.println(staticVariable);
        System.out.println("子类-静态初始化块");
    }
    /**子类-初始化块*/
    {
        System.out.println(partnerVariable);
        System.out.println("子类-初始化块");
    }
    /**子类-构造方法*/
    public JavaForClassExtendsInitialize(){
        System.out.println("子类-构造方法");
    }
    public static void main(String[] args) {
        System.out.println("子类-main方法");
        JavaForClassExtendsInitialize model = new JavaForClassExtendsInitialize();
    }

}


class Partner{
    /**父类-静态变量*/
    public static String partnerStaticVariable = "父类-静态变量";
    /**父类-变量*/
    public String partnerVariable = "父类-变量";
    /**父类-静态初始化块*/
    static {
        System.out.println(partnerStaticVariable);
        System.out.println("父类-静态初始化块");
    }
    /**初始化块*/
    {
        System.out.println(partnerVariable);
        System.out.println("父类-初始化块");
    }
    /**父类-构造方法*/
    public Partner(){
        System.out.println("父类-构造方法");
    }
}

执行以上代码,得到结果如下:

父类-静态变量
父类-静态初始化块
子类-静态变量
子类-静态初始化块
子类-main方法
父类-变量
父类-初始化块
父类-构造方法
父类-变量
子类-初始化块
子类-构造方法

猜你喜欢

转载自blog.csdn.net/yhy_it/article/details/52489581