二 java类初始化和对象初始化

——快乐是会传染的

 

类的初始化和对象实例化,似乎是没有什么必然联系,也没有可比性!但是很多时候的面试问题都会混在一起对比!如果说有联系的话,那就是初始化的时机不同,先后顺序不同。

1、从一个面试题引入

public class Test {
	public Test() {
		System.out.println("构造函数");
	}
	static{
		System.out.println("静态初始化模块");
	}
	public static void main(String[] args) {
		Test t1 = new Test();
		Test t2 = new Test();
	}
}

代码比较简单,运行结果是什么呢?为什么呢?

运行结果: 

静态初始化模块
构造函数
构造函数

结果并不重要,或许都看过类似面试题!但是为什么呢?先简述几个知识点

2、类的初始化--简述

类加载:把class文件读入内存,并生成java.lang.Class对象

连接:验证,准备,解析。

类初始化:主要对类变量(static修饰)进行初始化。

3、类初始化时机

 创建类实例。比如通过new 创建对象或通过反射创建对象(创建对象不仅类得到实例化,而且对象也会被实例化)。

 调用某个类的静态方法 或 操作静态属性(static修饰的)。比如上例中在main方法中调用Test.a

 使用反射创建某个类的Class帝乡,比如上例中:Class<Test> c= Test.class 或者 Class<Test> c = Class.forName("Test");此时对象并未初始化,只是类初始化。

 某个类被初始化时,它的父类将先被初始化。

 运行main(主类)方法时。

 4、对象实例化。通过new创建对象或通过反射

对象实例化,会调用对象的构造函数去创建对象,并返回对象引用。

如:Test t = new Test();  // 调用构造方法,返回引用赋值给t

5、分析:

执行 Test t1 = new Test(); 创建t1对象时,首先进行类初始化,输出:"静态初始化模块",然后对象初始化,输出:"构造函数"
执行 Test t2 = new Test(); 创建t2对象时,首先检查类是否初始化。以为类已经初始化过,所以不会再初始化。而t1与t2是不同的对象,所以t2初始化,再次输出:“构造函数”

6、类或者对象的初始化,会首先检查父类是否已经初始化,如果没有初始化,则先初始化父类。所以java.lang.Object会首先被初始化(它默认是所有类的父类,如果没有显示指出父类)

7、问题扩展:为Test类添加一个父类,代码如下

public class TestParent {
    public TestParent() {
        System.out.println("TestParent构造函数");
    }
    static{
        System.out.println("TestParent静态方法");
    }
}

public class Test extends TestParent{
    public Test() {
        System.out.println("Test构造函数");
    }
    static{
        System.out.println("Test静态初始化模块");
    }
    public static void main(String[] args) throws Exception {
        Test t1 = new Test();
        Test t2 = new Test();
    }
}

运行结果(初始化首先检查和初始化父类,如果父类还有父类,依次执行):

TestParent静态方法
Test静态初始化模块
TestParent构造函数
Test构造函数
TestParent构造函数
Test构造函数


时间:2016年1月14日09:10:18

posted @ 2016-01-14 09:52  车辙草  阅读(202)  评论(0编辑  收藏  举报