<%@ page contentType="text/html; charset=gb2312"%> 新手看招:JAVA程序的类加载及其反射机制
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
新手看招:JAVA程序的类加载及其反射机制
     发布者: 发布时间:2007-10-11

JAVA中类文件加载是动态的。JVM指令是被封装在了. class文件里面,而.class文件的加载过程是动态的,也就是说当我们用到的时候才会去加载,如果不用的话,就不会去加载我们的类。这里所说的用到包括两种方式,第一种就是new一个对象的时候(这个时候要特别注意,当设计到多态的时候,就会有一点点变化,这时候编译器会做一些优化,这样以来当加载的时候会提前加载设计到多态的类,关于这一点下面有个例子(example 1)来说明。另一种就是当一个类的静态代码被调用的时候。



java 代码//example 1 // Zoo.java abstract class Animal { Animal(){ System.out.println("Animal constructor"); } } class Tiger extends Animal { Tiger(){ System.out.println("Tig constructor "); } } class Dog extends Animal { Dog(){ System.out.println("Dog Constructor "); } } public class Zoo { private Animal am; //Example 1.1 //private Dog am; Example 1.2 private Tiger tiger; Zoo(){ tiger = new Tiger(); am = new Dog(); } public static void main(String [] args){ System.out.println("new Zoo before"); Zoo z = new Zoo(); System.out.println("new Zoo after "); } }




  当我们注释掉Example.1.1行时,运行Example1.2行,结果如下:

  Example 1.2

  分析以上两图的运行结果我们可以看出:当我们将子类对象赋值给父类时,编译器会做一点优化,于是加载器在还没有new 子类对象的时候已经加载了父类以及子类(example1.1结果),当不存在多态的时候,我们可以看到是当要new Dog()的时候才会加载Dog以及父类。无论何种方式,在new之前,类确实已经加载到了内存中。

  JAVA为我们提供了两种动态机制。第一种是隐式机制。其实new一个对象和调用类的静态方法时,就是隐式机制在工作。第二种是显示机制。显示的机制又有两种策略(第一种是用java.lang.Class的forName(String str)方法,第二种是用java.lang.ClassLoader的loadClass())。

  第一种:利用forName方法

  当我们查API文档就会发现forName方法有两种形式。分别如下:


public static Class<?> forName(String className) throws ClassNotFoundException public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException




  先来说说第二种方法:第二个方法值得注意的就是第二个参数boolean initialize,如果我们把这个参数设置为false,那么当我们加载完类后就不会执行静态代码和静态的初始化动作。只有当我们new一个对象的时候才会初始化。而第三个参数是用来指明类的加载器的。

  如果查看java.lang.Class类的源代码,上述两种方法最终都会调用Class类中的私有的native方法forName0(),此方法的声明如下:


private static native Class forName0(String name, boolean init , ClassLoader loader) throws ClassNotFoundException;




  所以当我们调用Class.forName(name )时,其实是在方法内部调用了:


forName0(name, true, ClassLoader.getCallerClassLoader());



  当我们调用Class.forName(name, initialize, loader )的时候,实际上此方法内部调用了:


forName0(name, initialize, loader);




  下面看一个例子,如果方法中第二个参数为false的情况:


java 代码//example 2.1 // Zoo.java abstract class Animal { static { System.out.println("Animal static code block "); } Animal(){ System.out.println("Animal constructor"); } } class Tiger extends Animal { Tiger(){ System.out.println("Tig constructor "); } } class Dog extends Animal { Dog(){ System.out.println("Dog Constructor "); } } public class Zoo { public static void main(String [] args)throws Exception { System.out.println("new Zoo before"); Zoo z = new Zoo(); Class c = Class.forName("Dog",false,z.getClass().getClassLoader()); System.out.println("initilize before "); Animal dog = (Animal)c.newInstance(); System.out.println("new Zoo after "); } }




  类加载完成后并没有立即执行静态初始化代码,而是到了实例化的时候才进行了静态初始化。有时候我们会说静态代码是在类第一次被加载时执行的,并且只执行一次。其实这是对与new一个对象,第一次访问类的静态代码以及第二个参数为true时而言的,对于动态的加载来说,如果forName方法的第二个参数设置为false,那么就是在实例化的时候才会执行静态初始化。当然默认情况下第二个参数是true.

  第二种方法:利用Class对象获取的ClassLoader装载。

  下面是一个简单的例子:


java 代码//Example 2.2 //Zoo.java abstract class Animal { static { System.out.println("Animal static code block "); } Animal(){ System.out.println("Animal constructor"); } } class Tiger extends Animal { Tiger(){ System.out.println("Tig constructor "); } } class Dog extends Animal { Dog(){ System.out.println("Dog Constructor "); } } public class Zoo { public static void main(String [] args)throws Exception { Class c = Zoo.class; ClassLoader loader = c.getClassLoader(); System.out.println("loader before"); Class dog = loader.loadClass("Dog"); System.out.println("instance before "); Animal an = (Animal)dog.newInstance(); } }




  loader完成以后并没有立即进行静态代码的执行。只有当newInstance()的时候才执行静态初始化,这和把public static Class forName(String name, boolean initialize, ClassLoader loader)的第二个参数指定为false的情况完全一样。其实每当我们写完一个编译单元以后就会得到一个.calss文件,这个文件中就包含了该类的Class对象。JVM就是利用这个class对象来进行动态装载类的。
(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
对于JSP中表单数据存储的一种通用方法
构造 JSP/Javabean 开发和发布环境简介
快速、简便的使用AJAX技术操作的三部曲
谈谈JAVA并发程序设计现状和发展前景
新手入门:写Java程序的三十个基本规则
Java SE 6新特性:Instrumentation
 
最近评论:
        
鍥炲
        
那个雨天的想法!
wow gold,wow power leveling.wow power leveling,wow power leveling, max(6835)
        
如果真的有来生!
四川旅游,九寨沟旅游,稻城亚丁旅游,四姑娘山旅游,海螺沟旅游,西藏旅游, max(6937)
        
春暖花开
world of warcraft power leveling,arena power leveling,wow power leveling,honor power leveling,wow power leveling,wow powerleveling,skill power leveling,Reputation power leveling,Professions power leveling,lotro power leveling,lotro powerleveling,world of warcraft leveling,wow gold,world of warcraft gold, t7r6a7dh
        
那天的情景!
Maple Story mesos,MapleStory mesos,ms mesos,mesos,SilkRoad Gold, max(9401)
        
轻轻走过你的窗前!
world of warcraft gold,cheap world of warcraft gold,warcraft gold,world of warcraft gold,cheap world of warcraft gold,warcraft gold max(6844)
        
没有情人的情人节!
wow gold,wow power leveling.wow power leveling,wow power leveling, max(3929)
        
没有情人的情人节!
wow gold,wow power leveling.wow power leveling,wow power leveling, max(1311)
        
远方的你!
world of warcraft gold,wow gold,a href="http://www.gogoer.com">world of warcraft gold,cheap world of warcraft gold max(6575)
        
我想告诉你!
final fantasy xi gil,final fantasy xi gil,final fantasy xi gil,world of warcraft gold,cheap world of warcraft gold max(3236)
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号