类的加载,连接,初始化详解

来源:互联网 发布:内存整型数据 编辑:程序博客网 时间:2024/06/10 12:07

以前对类的生命周期这个问题有点迷糊,现在特来写写,希望可以理清这个过程的思路!
我们知道类的生命周期分为:类的加载,类的连接,类的初始化。

lifecyle
    ㈠类的加载没什么说得,就是由类加载器读入类的.class二进制数据到内存的过程,并在内存堆区创建一个与之对应的Class对象。
    ㈡类的连接包括:验证,准备,解析,验证过程就是java虚拟机对加载进来的.class文件结构等方面的检查。
准备阶段是JVM为类的静态变量分配空间(注意类的static final常量是编译期就确定的),并且设置默认的初始值,如int 类型赋予0,boolean 类型赋予false等等。类的解析:JVM把类二进制数据中的符号引用替换为直接引用(这一步不是必须的)。
㈢类的初始化:在这个阶段,主要是为静态变量赋予真正的初始值。有两种途径:一种是在声明静态变量时就初始化,另一种是通过static块来初始化,看看下边的例子。
public class Test
{
    private static int a = 1; //变量声明时进行初始化
    private static int b;
    static
    {
        b = 2; //通过静态语句块来初始化
    }
}
它们的初始化顺序是按照语句出现的先后顺序依次执行.下面这几点比较重要。
Java虚拟机执行初始化一个类包含以下几步:
1.如果这个类没有被加载和连接,那么就先加载和连接。
2.如果类存在直接的父类,并且父类还没有被初始化,则先进行父类的初始化工作。
3.如果存在初始化语句,则依次执行这些语句。
class Base
{
    private static int a = 1;
    static
    {
        System.out.println("init Base");
    }
}

class Sub extends Base
{
    public static int b = 3;
    static
    {
        System.out.println("init Sub");
    }
}

public class Test
{
    static
    {
         System.out.println("init Test");
    }
    public static void main(String[] args)
    {
         System.out.println("b = " + Sub.b);
    }
}
执行输出:
init Test
init Base
init Sub
b = 3
这里还有一个问题,就是初始化时机。什么时候会初始化呢?看看下面的代码:
class Sample
{
    public static final int a = 5 * 8;
    Static
    {
         System.out.println("init Sample");
    }
}
public class Test
{
    public static void main(String[] args)
    {
         System.out.println(" a = " + Sample.a); 
    }
}
如果你认为会打印下面,那就错了 
System.out.prinltn("init Sample");
a = 40
执行,发现打印:
a = 40 
这里边就涉及到类初始化时机,即什么时候才初始化一个类呢?书上是这样说的:java虚拟机只有在程序
首次主动使用一个类或接口时才会对其进行初始化,只有6种活动被看作是程序对类的主动使用
1.创建类的实例 2.调用类的静态方法   3.访问某个类或接口的静态变量,或者对该静态变量赋值
4.调用类的反射方法,如:Class.forName()    5.初始化一个类的子类,可以看作是对父类的主动使用,所以
会初始化父类   6.jVM启动时旁观标明为启动类的类。如在命令窗口执行:java A,则A就是启动类,JVM会最先初
始化它。
除此以外都不看作是首次主动使用,下面举几个例子如:
1.对于final类型的static变量,如果在编译时就能计算出来,就是编译时常量,像上面的例子,
显然5 * 8 = 40,认为是被动使用。
2.初始化一个类,必须先初始化它的父类,对于接口并不是这样,所以也是被动使用。并不会初始化它的父接口。

总之,对于类的生命周期,初始化最令人疑惑的,希望大家看了能有所帮助。

博客转载处 http://zhuhanshan.blog.51cto.com/480685/102744