posts - 11,  comments - 0,  trackbacks - 0

 

在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)  编辑  收藏

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


网站导航:
 

<2011年3月>
272812345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用链接

留言簿(2)

随笔档案

文章分类

相册

最新随笔

搜索

  •  

最新评论

阅读排行榜

评论排行榜