廉颇老矣,尚能饭否

java:从技术到管理

常用链接

统计

最新评论

类的 初始化顺序【转载】

class ClassA{
    
static{
        System.out.println(
"ClassA's static.");
    }

    
public ClassA(){
        System.out.println(
"ClassA's constructor.");
    }

}

class ClassB extends ClassA{
    
static{
        System.out.println(
"ClassB's static.");
    }

    
public ClassB(){
        System.out.println(
"ClassB's constructor.");
    }

}

public class TestClass {

    
public static void main(String[] args) {
        ClassA a 
= new ClassB();
        System.out.println(
"===============");
        a 
= new ClassB();
    }


}

输出:
ClassA's static.
ClassB's static.
ClassA's constructor.
ClassB's constructor.
===============
ClassA
's constructor.
ClassB's constructor.
我个人分析如下:
当执行到ClassA a = new ClassB();时开始加载ClassB,这里因为ClassB继承ClassA,所以加载ClassA,在加载ClassA的时候执行输出:ClassA's static.。
ClassA加载完后,加载ClassB,这时执行结果为:ClassB's static.。两个类都加载完后开始构建对象。
在构建ClassB对象时,得先构建父类对象ClassA,所以执行分别为:ClassA's constructor.
ClassB's constructor.那么这句话完了。
 
到a=new ClassB();时,由于ClassA,ClassB已经被加载过,在内存中。所以只是简单的进行构建对象。输出:ClassA's constructor.
ClassB's constructor.
希望大家多多指教。
============================
类的初始化分为类加载后的初始化和类实例化后的初始化,当new一个类的时候,如果此类没有被加载到vm中,vm会先加载此类,当加载完成后vm会立即执 行此类中的所有的静态初始化代码。加载完成后,vm会为实例分配内存,然后执行实例初始化代码,最后是执行构造方法返回新建对象的引用。

静态初始化代码是被static修饰的字段或静态代码段,实例初始化代码是类中声明并初始化并且没有被static修饰的字段,还有就是在类中被大括号括起来的代码段
===========================
关键是要把握几点

1. 对象实例初始化之前要初始化类实例,它们对应字节码的方法名分别是 cinit() 和init(),类的静态块编译后会放在 cinit() 方法中,{} 括起来的非静态块会放到 init() 方法中。

2. 构造子对象实例前必须构造出父对象实例,当然在构造子类实例前必须构造父类实例。

就这么两点,这里用了类实例和对象实例。区别是,比如有个类A,分别构造了
A a1 = new A();
A a2 = new A();
A a3 = new A();

三个是对象实例,但是只要同一个类加载器加载的,那么
a1.getClass()和a2.getClass(),a3.getClass() 就是同一个实例,叫做它们的类实例。

这里只简单的说了是由同一个类加载器加的,如果延展开来就会比较复杂。根据类加载器的委托机制和可见性原则还会有不同的情况。


柳德才
13691193654
18942949207
QQ:422157370
liudecai_zan@126.com
湖北-武汉-江夏-庙山

posted on 2009-03-31 17:26 liudecai_zan@126.com 阅读(161) 评论(0)  编辑  收藏 所属分类: 程序人生


只有注册用户登录后才能发表评论。


网站导航: