Java类的初始化

来源:互联网 发布:暴风vr电视直播软件 编辑:程序博客网 时间:2024/05/29 02:32

大家都知道类的初始化顺序,有父类的时候,顺序是:

–> 父类的静态成员(包括静态变量和静态代码块)
–> 子类的静态成员(包括静态变量和静态代码块)
–> 父类的普通成员(普通成员变量和普通代码块)和构造函数
–> 子类的普通成员(普通成员变量和普通代码块)和构造函数

我个人觉得大家平时说的初始化可以分成两类,也即两个阶段,首先是类的初始化,其次是对象的初始化。静态成员初始化属于类初始化,普通成员和构造函数初始化属于对象初始化。

原因如下示例:

class H {    static int s = 1;    static {        System.out.println("first static block");        System.out.println("ordinary var s initial: " + s);        s = 2;        System.out.println("ordinary var s afer change: " + s);    }    public int a;    {        System.out.println("first ordinary block");        System.out.println("ordinary var a : " + a);    }    static {        System.out.println("last static block " + s);    }    public H() {        System.out.println("constructor");    }    {        System.out.println("last ordinary block");    }}

在main函数里

new H();new H();

则运行结果如下

//静态成员first static blockordinary var s initial: 1ordinary var s afer change: 2last static block 2//普通成员first ordinary blockordinary var a : 0last ordinary block//构造函数constructor//普通成员first ordinary blockordinary var a : 0last ordinary block//构造函数constructor

代码就不细讲了,很明显可以看到,在两次创建对象的过程中,静态成员初始化了一次,对象成员(姑且这么叫先)初始化两次。当然,类静态变量存放在方法区,实例变量存在于类对象对应的堆内存中,每创建一个对象就在堆内存开辟一个内存区域存放对象成员等内容,所以也就很明白了。


我要说的是另外一个值得注意的地方,就是Class.forName(String name)方法。Class.forName()方法返回的是一个类(Class对象),作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。

在main函数里调用该方法

try {        Class.forName("H");    } catch (ClassNotFoundException e) {        e.printStackTrace();    }

则运行结果如下

//静态成员first static blockordinary var s initial: 1ordinary var s afer change: 2last static block 2

只有类静态成员初始化了。
JDK文档里是这样说的:

A call to forName("X") causes the class named X to be initialized.

另外,还有一个类加载方法forName(String name, boolean initialize, ClassLoader loader),根据参数名称就可以理解参数的含义,其中第二项参数就是确定是否需要初始化类。

那么在其他函数里这样调用(因为有this关键字不能在静态的main方法里用):

try {    //initialize = false    Class.forName("H",false,this.getClass().getClassLoader());  } catch (ClassNotFoundException e) {    e.printStackTrace();}

运行后什么也没有显示,即没有进行类的初始化工作,但是没有抛异常,说明类已经加载完成了,估计连接也已经完成。

再测试如下,创建实例对象:

try {    Class<?> c = Class.forName("H",false,this.getClass().getClassLoader());    c.newInstance();} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {    e.printStackTrace();}

则运行结果如下

//静态成员first static blockordinary var s initial: 1ordinary var s afer change: 2last static block 2//普通成员first ordinary blockordinary var a : 0last ordinary block//构造函数constructor

new H(); 是一样的效果。


参考
Class.forName
Java初始化顺序

0 0
原创粉丝点击