在java程序中每一个类都有一个Class对象,被保存在同名的.Class对象当中,JVM会使用类加载器加载Class文件生成类的对象信息.
当我们创建一个类的对象或者调用这个对象的静态方法,jvm会自动加载类的对象信息
获得类的对象信息
我们一般常用用两种方式获得类的对象信息.
1. 我们可以用Class.forName()方法动态的根据类名获得一个类的Class对象.
1: /**
2: * 使用此方法为自动初始化静态变量和执行static块的代码
3: * 如果找不到对象会抛出一个ClassNotFoundException
4: */
5: Class second = Class.forName("classLoad.Second");
2. 我们还可以用Class class = ClassName.class 来直接获取一个类的类型信息,但用它和Class.forName()获取类的对象
引用信息在静态块时的执行时间上不同,看下面的例子:
一个普通类信息
1: interface Interface{
2: public static String interFlag = "接口";
3:
4: }
5:
6: class Parent implements Interface{
7: public static String parntFLAG = "父类静态变量";
8: static{
9: final String flag2 = "flag2";//static 区中只能用final修饰
10: System.out.println("我在父类静态区里面!"+parntFLAG);
11: }
12:
13: public Parent(){
14: System.out.println("我在父类构造函数里面!");
15: }
16: }
17:
18:
19: class Son extends Parent{
20: public static String sonFLAG = "子类类静态变量";
21: static{
22: System.out.println("我在子类静态区里面!"+sonFLAG);
23: }
24:
25: public Son(){
26: System.out.println("我在子类构造函数里面!");
27: }
28: }
1: interface Interface{
2: public static String interFlag = "接口";
3:
4: }
5:
6: class Parent implements Interface{
7: public static String parntFLAG = "父类静态变量";
8: static{
9: final String flag2 = "flag2";//static 区中只能用final修饰
10: System.out.println("我在父类静态区里面!"+parntFLAG);
11: }
12:
13: public Parent(){
14: System.out.println("我在父类构造函数里面!");
15: }
16: }
17:
18:
19: class Son extends Parent{
20: public static String sonFLAG = "子类类静态变量";
21: static{
22: System.out.println("我在子类静态区里面!"+sonFLAG);
23: }
24:
25: public Son(){
26: System.out.println("我在子类构造函数里面!");
27: }
28: }
使用这种方法引用类的对象不会始化静态变量和执行静态块信息,这些代码方法会在首次引用时执行.
如下引用父类的静态变量,不会执行子类的静态块.
1: public class ClassLoad {
2: public static void main(String[] args) throws ClassNotFoundException {
3:
4: //Son son = new Son();
5: /**
6: * 我们使用一个类的时候需要进行以下3项工作.
7: * 1.加载,
8: * 2.链接
9: * 3.初始化,此步会初始化静态变量和执行静态块信息,但是这种方法会在
10: * 真正调用方法时执行
11: */
12: Class son = Son.class;
13: System.out.println("静态区的初始化会在调用时执行!");
14: // parntFLAG 是父类的静态变量
15: // 此处只会执行父类的静态快
16: System.out.println(Son.parntFLAG);
17:
18: /**
19: * 运行结果
20: *静态区的初始化会在调用时执行!
21: *我在父类静态区里面!父类静态变量
22: *父类静态变量
23: */
24: }
25: }
打印子类的静态变量,所有的代码都会执行
1:
2: public class ClassLoad {
3: public static void main(String[] args) throws ClassNotFoundException {
4:
5: //Son son = new Son();
6: /**
7: * 我们使用一个类的时候需要进行以下3项工作.
8: * 1.加载,
9: * 2.链接
10: * 3.初始化,此步会初始化静态变量和执行静态块信息,但是这种方法会在
11: * 真正调用方法时执行
12: */
13: Class son = Son.class;
14: System.out.println("静态区的初始化会在调用时执行!");
15: // parntFLAG 是父类的静态变量
16: // 此处只会执行父类的静态快
17: System.out.println(Son.sonFLAG);
18:
19: /**
20: * 运行结果
21: * 静态区的初始化会在调用时执行!
22: * 我在父类静态区里面!父类静态变量
23: * 我在子类静态区里面!子类类静态变量
24: * 子类类静态变量
25: */
26: }
27: }
但是使用Class.forName 类加载时就会完成初始化工作.
1: public class ClassLoad {
2: public static void main(String[] args) throws Exception {
3: /**
4: * 使用Class.forName会自动加载所有静态区的信息
5: */
6: Class son = Class.forName("classLoad.Son");
7: Son instance = (Son)son.newInstance();
8: /*
9: * 执行结果
10: * 我在父类静态区里面!父类静态变量
11: * 我在子类静态区里面!子类类静态变量
12: * 我在父类构造函数里面!
13: * 我在子类构造函数里面!
14: */
15:
16: }
17: }
posted on 2011-03-13 18:41
小晖 阅读(875)
评论(0) 编辑 收藏