码迷,mamicode.com
首页 > 其他好文 > 详细

类加载之初始化(包括静态代码块讲解)

时间:2017-05-24 00:48:59      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:类构造   多个   构造器   代码块   ext   执行   类变量   构造   对象创建   

开始我们先来看一段代码

package classLoader;

class a {
    public a() {
        System.out.println("init a");
    }
    
    public void say(){
        System.out.println("say a");
    }
    
    {
        System.out.println("block a");
    }
    
    static {
        System.out.println("static a");
    }    
}

public class b extends a {
    
    public b() {
        System.out.println("init b");
    }
    
    {
        System.out.println("block b");
    }
    
    public void say(){
        System.out.println("say b");
    }
    
    static {
        System.out.println("static b");
    }        
    
    public static void main(String[] args) {
        System.out.println("主程序开始!");
        a test = new b();  //进行类的初始化
        test.say();
        System.out.println("重新创建对象!");
        test = new b(); 
            
    }
}

运行结果:技术分享

我们可以看出静态代码优先于普通代码快更优先与构造函数。同时静态代码块在对象创建前就运行了静态代码块,总是先运行父类代码再运行子类代码,我们也可以说父类代码先行于子类代码块。而在给test重新赋予一个新的a对象时并没有执行静态代码快。接下来我们来分析出现这些现象的原因。

 

首先我们先来聊聊类的初始化

java虚拟机对于5种情况必须进行初始化。

  1. 使用new关键字实例化对象吗,读取或设置一个静态字段,以及调用一个静态方法
  2. 进行反射调用的时候,如果没有进行初始化先触发其初始化。
  3. 初始化一个类时,发现其父类没有进行初始化,则需要先进性父类的初始化。
  4. 虚拟机启动需要执行一个主类时(包含main()方法的类)。
  5. 使用jdk1.7的动态语言支持时如果一个MethodHandle实例最后的解析结果REF_getstatic,REF_putstatic,REF_invokeStatic的句柄时,并且其没有进行初始化则先出发其初始化

在准备阶段进行系统要求的初始值赋值。而在初始化阶段执行类构造器<clinit>()方法的过程。。

<clinit>()所发挥的作用

<clinit>()是初始化阶段主要执行的代码。根据程序员的要求进行变量的赋值和其他资源的调用。<clinit>()方法会自动收集所有类变量赋值和静态代码块。该方法与构造函数不同,他不需要显式的调用父类构造器。在执行子类的<clinit>()方法时父类的<clinit>()已经执行完毕。也就意味着父类的构造器先行于子类的构造器。所以会先输出父类静态代码块的内容,再输出子类静态代码块的内容。

注意:<clinit>()方法不是必须的,如果没有静态代码,块也没有变量的赋值。那么其可以不生成<clinit>()方法

<clinit>()是线程安全的,但如果一个县城的<clinit>()耗时很长会导致多个进程阻塞。也就是说stati代码块应用不当会造成进程阻塞。

Q&A


在给test重新赋予一个新的a对象时并没有执行静态代码快的原因?

该类已经初始化了,不用再进行初始化,故不需要进行初始化,也就不需要执行<clinit>(),自然也就不会输出静态代码的内容。

静态代码块,普通代码块,构造函数运行顺序?

由程序运行结果可知:静态代码块>普通代码块>构造函数

注意;父类代码先行于子类代码,代码进行初始化5种情况的第3种

类加载之初始化(包括静态代码块讲解)

标签:类构造   多个   构造器   代码块   ext   执行   类变量   构造   对象创建   

原文地址:http://www.cnblogs.com/boWatermelon/p/6896690.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!