读书人

Java软件工程师从笨鸟到初学者之(九十

发布时间: 2012-09-24 13:49:41 作者: rapoo

Java程序员从笨鸟到菜鸟之(九十四)深入java虚拟机(三)——类加载器(中)类的初始化


上接深入java虚拟机——深入java虚拟机(二)——类加载器详解(上),在上一篇文章中,我们讲解了类的生命周期的加载和连接,这一篇我们接着上面往下看。


类的初始化:在类的生命周期执行完加载和连接之后就开始了类的初始化。在类的初始化阶段,java虚拟机执行类的初始化语句,为类的静态变量赋值,在程序中,类的初始化有两种途径:(1)在变量的声明处赋值。(2)在静态代码块处赋值,比如下面的代码,a就是第一种初始化,b就是第二种初始化


不知道你做对没有,反正我刚开始做错了。好,现在我来解释一下为什么会是这个答案。在给出解释之前,我们先来看一个概念:

Java程序对类的使用方式可分为两种

主动使用

被动使用

?所有的Java虚拟机实现必须在每个类或接口被Java程序“首次主动使用”时才初始化他们

主动使用(六种)

创建类的实例

访问某个类或接口的静态变量,或者对该静态变量赋值

调用类的静态方法

反射(如Class.forName(“com.bzu.csh.Test”))

初始化一个类的子类

Java虚拟机启动时被标明为启动类的类(Java Test)

OK,我们开始解释一下上面的答案,程序开始运行,首先执行main方法,执行main方法第一条语句,调用Singleton类的静态方法,这里调用Singleton类的静态方法就是主动使用Singleton类。所以开始加载Singleton类。在加载Singleton类的过程中,首先对静态变量赋值为默认值,

Singleton=null

counter1 = 0

Counter2 = 0

给他们赋值完默认值值之后,要进行的就是对静态变量初始化,对声明时已经赋值的变量进行初始化。我们上面提到过,初始化是从类文件从上到下赋值的。所以首先给Singleton赋值,给它赋值,就要执行它的构造方法,然后执行counter1++;counter2++;所以这里的counter1 = 1;counter2 = 1;执行完这个初始化之后,然后执行counter2的初始化,我们声明的时候给他初始化为0 了,所以counter2 的值又变为了0.初始化完之后执行输出。所以这是的

counter1 = 1

counter2 = 0

类初始化步骤

(1)假如一个类还没有被加载或者连接,那就先加载和连接这个类

(2)假如类存在直接的父类,并且这个父类还没有被初始化,那就先初始化直接的父类

(3)假如类中存在初始化语句,那就直接按顺序执行这些初始化语句

在上边我们我们说了java虚拟机实现必须在每个类或接口被Java程序“首次主动使用”时才初始化他们,上面也举出了六种主动使用的说明。除了上述六种情形,其他使用Java类的方式都被看作是被动使用,不会导致类的初始化。程序中对子类的“主动使用”会导致父类被初始化;但对父类的“主动”使用并不会导致子类初始化(不可能说生成一个Object类的对象就导致系统中所有的子类都会被初始化)

当java虚拟机初始化一个类时,要求它的所有的父类都已经被初始化,但这条规则并不适用于接口。

在初始化一个类时,并不会先初始化它所实现的接口

在初始化一个接口时,并不会先初始化它的父接口

因此,一个父接口并不会因为它的子接口或者实现类的初始化而初始化。只有当程序首次使用特定接口的静态变量时,才会导致该接口的初始化。只有当程序访问的静态变量或静态方法确实在当前类或当前接口中定义时,才可以认为是对类或接口的主动使用 。如果是调用的子类的父类属性,那么子类不会被初始化。

6楼lmj810960397昨天 22:48
很诚实的说,我错了,我也以为是1,1
5楼shuishoujushi昨天 15:26
我也做成1,1了。试问楼主,初做此题,正确率几何
Re: csh624366188昨天 21:44
回复shuishoujushin目前还没有人给我说第一次就做对了。。
4楼bzu902前天 15:34
做错了。。。
Re: csh624366188前天 15:37
回复bzu902n你的答案写下来啊。。亲、
3楼zcjwsrf前天 15:22
我真的泪流满面。。。。我错了
Re: csh624366188前天 15:24
回复zcjwsrfn说好的答案呢、
2楼dnf7f前天 15:11
继续啊。。。学习中
1楼csh624366188前天 15:01
come on。。。

读书人网 >其他相关

热点推荐