网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.Java IO 包中的Decorator模式.
.JAVA进阶:一个简单Thread缓冲池.
.想要开始为 Java 手机开发应用程.
.Java Script与Java Applet的综合.
.用java实现RSA算法.
.详细解析Java中抽象类和接口的区.
.初学Java入门--类与对象.
.J2ME综合-J2ME应用程序内存优化.
.Effective java学习笔记8.
.学习心得:Java基本功之Referenc.
.java写的文件浏览器.
.Maven起步——教你开始使用Maven.
.Java 开发环境的过去、现在和将来.
.也谈面向对象.
.在Eclipse RCP中实现反转控制(Io.
.javabean与ejb的区别.
.java开发技巧:对jar包进行再次修.
.java硬件.
.JAVA基础知识(3).
.JBuilder2005+JBOSS+Oracle9i的环.

java类加载的表现形式

发表日期:2008-1-5



   Java中的类是动态加载的,我们先看一下我们常用的类加载方式,先有一个感性的熟悉,才能进一步
深入讨论,类加载无非就是下面三种方式。
class A{}
class B{}
class C{}
public class Loader{
    public static void main(String[] args) throws Exception{
       Class aa=A.class;
       Class bb=Class.forName("B");
       Class cc=ClassLoader.getSystemClassLoader().loadClass("C");
    }
}

我们先看.class字面量方式,很多人可能不知道这种方式,因为这种用法不是一般java语法。
通过javap我们可以发现,这种方式的大致等价于定义了一个静态成员变量
    static Class class$0;(后面的编号是增长的)
你可以试图再定义一个  static Class class$0,应该会收到一个编译错误(重复定义)。
Class aa=A.class;
就相当于

    if(class$0==null){
 try{
           Class.forName("A");
 }
 cacth(ClassNotFoundException e){
    throw new NoClassDefFoundError(e);
 }
    }
    Class aa=class$0;
    可以很清楚的看到,这种类的字面量定义其实不是加载类的方式,而是被编译器处理了,实质上是使用了Class.forName方法,但是使用这种方式有一个很大的好处就是不用处理异常,因为编译器处理的时候假如找不到类会抛出一个NoClassDefFoundError.也许你觉得需要处理ClassNotFoundException这种异常,事实上99%的情况下我们可以把这种异常认为是一个错误。
    所以大部分情况我们使用这种方式会更简洁。
    最常用的方式就是Class.forName方式了,这也是一个通用的上层调用。这个方法有两个重载,可能很多人都忽略了第二个方法。
public static Class forName(String name) throws ClassNotFoundException
public static Class forName(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException
第二个方法后面多了两个参数,第二个参数表示是否初始化,第三个参数为指定的类加载器。
在上面的例子中:
Class bb=Class.forName("B");
等价于
Class bb=Class.forName("B",true,Loader.class.getClassLoader());
    这里要具体说一下这个类的初始化这个参数,假如这个参数为false的话,类中的static成员不会被初始化,static语句块也不会被执行。
    也就是类虽然被加载了,但是没有被初始化,不过在第一次使用时仍然会初始化。
    所以我们有时候会看到Class.forName("XXX")。newInstance()这样的语句,为什么这里要创建一个不用的实例呢?不过是为了保证类被初始化(兼容以前的系统)。
    其实第二个方法是比较难用的,需要指定类加载器,假如不指定而且又没有安装安全治理器的化,是无法加载类的,只要看一下具体的实现就明白了。
    最本质的方式当然是直接使用ClassLoader加载了,所有的类最终都是通过ClassLoader加载的,Class cc=ClassLoader.getSystemClassLoader()。loadClass("C");这里通过使用系统类加载器来加载某个类,很直接的方式,但是很遗憾的是通过这种方式加载类,类是没有被初始化的(也就是初始化被延迟到真正使用的时候)。不过我们也可以借鉴上面的经验,加载后实例化一个对象Class cc=ClassLoader.getSystemClassLoader()。loadClass("C")。newInstance()。
    这里使用了系统类加载器,也是最常用的类加载器,从classpath中寻找要加载的类。
    java中默认有三种类加载器:引导类加载器,扩展类加载器,系统类加载器。
    java中的类加载有着规范的层次结构,假如我们要了解类加载的过程,需要明确知道哪个类被谁加载,某个类加载器加载了哪些类等等,就需要深入理解ClassLoader的本质。

上一篇:编程基础入门:Java修饰词的总结 人气:508
下一篇:Java入门:缓冲区溢出编程心得 人气:509
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐