读书人

种的加载方法:Class.forName与ClassL

发布时间: 2012-09-08 10:48:07 作者: rapoo

类的加载方法:Class.forName与ClassLoader.loadClass

?Class.forName和ClassLoader.loadClass方法都用来动态的加载一个类(都返回一个java.lang.Class对象),区别在于他们使用的ClassLoader和是否执行类的初始化。

1.1????? Class.forName

这是一个类方法,该方法除了加载类到JVM中,还会执行类的初始化,即类的静态初始化。

?

使用Class.forName最常用的形式是Class.forName(String qualifiedClassName), 如写JDBC程序常用到的加载某个数据库Driver到jvm的代码:

Class.forName("com.mysql.jdbc.Driver");

该函数使用调用者的ClassLoader, 即调用该行代码的类所使用的ClassLoader,返回一个参数名所对应的Class对象。

另外还有一个带三个参数的forName方法, Class.forName(String, boolean, ClassLoader),参数分别用来指定类名,是否初始化和要使用的ClassLoader。

1.2????? ClassLoader.loadClass

这是一个实例方法,可以使用一个特定的ClassLoader来加载一个类。该方法不会执行类的初始化,只由当该类第一次被使用时才会执行类的初始化,比如调用该类的一个静态方法或创建该类的一个对象。

1.3????? 使用哪一个方法

1.3.1?????? ClassLoader

不同的ClassLoader加载类时会从不同的位置来查找类的.class文件,所以如果要加载的类不在默认的查找位置时,就应该指定要使用的ClassLoader,否则会得到java.lang.ClassNotFoundException的错误。为了灵活性,你应该总是提供一个来参数指定ClassLoader而不是使用默认的ClassLoader,即使用带三个参数的forName或loadClass方法。关于不同的ClassLoader如何查找及加载类请参考ClassLoder一文。

1.3.2?????? 是否要执行类初始化

在上面加载Mysql Driver的例子中,我们本身并不需要创建MySqlDriver对象,只需要加载Driver到JVM,并执行类的初始化(可能执行注册自己到Driver Manger的代码)。所以可以使用forName方法,如果使用ClassLoader.loadClass则需要像下面这样:

ClassLoader cl = …;

cl.loadClass("com.mysql.jdbc.Driver").newInstance(); //创建对象仅仅为了执行类初始化,对象本身并不会被使用。

?

如果已知类的初始化是一个比较耗时的过程,则可以将其初始化推迟到该类被一次使用时。另外执行类的初始化代码失败会抛出java.lang.ExceptionInInitializerError异常。此时加载的类就变得不可用。类的初始化错误往往很难跟踪,所以如果要在一个特定点捕获并处理该异常就可以使用Class.forName并放在一个try块中。但是不要试图重新加载该类,因为一个类只能被同一个ClassLoader加载一次。

?

1.4????? 参考:

[ldcs] http://www.javaworld.com/javaworld/javaqa/2003-03/01-qa-0314-forname.html?page=1. 2003.03

?

?

?

读书人网 >编程

热点推荐