论坛首页 Java版

请问如何理解类的装载,连接,初始化?

浏览 3074 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2005-04-06
生成一个类的实例的两种方式:
1.
[code:1]
Driver driver = new com.mysql.jdbc.Driver();
[/code:1]
2.
[code:1]
Class class =  Class.forName("com.mysql.jdbc.Driver");
Driver driver = (Driver)class.newInstance();
[/code:1]
我的理解是第一种方式,就是类的装载,连接,初始化一次性完成了。
而第二种方式,Class.forName("com.mysql.jdbc.Driver")形成一个Class的实例就相当于类的装载过程,class.newInstance()就相当于类的连接,初始化过程。
而类的装载过程简单的说就是产生一个二进制流并解析它然后创建Class的实例。如果我用第二种方式生成一个类的实例,把生成的Class的实例存入一个Map中,以后再次生成这个Class的实例时从这个Map中找而不是再次Class.forName("...")有没有意义?
   
最后更新时间:2005-04-06
以后可以不用forName(...)方法再生成该类型的Class实例。除非你需要生成不同型别的实例。一个Class的实例代表一种型别。
   
0 请登录后投票
最后更新时间:2005-04-06
那我对第一种方式的理解有没有错?就是说如果new 一个对象就相当于一次性的完成装载,连接,初始化的过程,难道说每new一个对象都需要执行一次装载的过程?
   
0 请登录后投票
最后更新时间:2005-04-06
呵呵!这个嘛!一个类在产生它自己的实例的时候或是用到该类的static方法或是域的时候是装载它自己对应的Class实例的。你理解的没有错,但是在new同一个类第二次的时候它就不装载Class实例了。因为该类已经被装载了。你可以用代码测试一下。如:

Integer number1 = new Integer(1);
Integer number2 = new Integer(2);
System.out.println(number1.getClass() == number2.getClass());

结果是true.
   
0 请登录后投票
最后更新时间:2005-04-06
楼上楼下不要跑题.

我也不明白为什么用方法2来写
   
0 请登录后投票
最后更新时间:2005-04-06
那么,是不是我把Class实例放入一个Map中也是没意义的,因为我运行下面的代码,结果也是true.
[code:1]
public class LoaderClassTest {
public static void main(String[] args) throws Exception {
Class cla = Class.forName("java.lang.Integer");
Class cla1 = Class.forName("java.lang.Integer");
System.out.println(cla == cla1);
}
}
[/code:1]
   
0 请登录后投票
最后更新时间:2005-04-06
两个forName(...)方法返回的class实例的reference都是一样的。因为它们的型别是一样的,当然是true啊!一个型别在被装载的时候就产生一个Class实例。(包括基本类型int,double,等等都有对应它们型别的Class实例)。
   
0 请登录后投票
最后更新时间:2005-04-06
kofandkingmax 写道
两个forName(...)方法返回的class实例的reference都是一样的。因为它们的型别是一样的,当然是true啊!一个型别在被装载的时候就产生一个Class实例。(包括基本类型int,double,等等都有对应它们型别的Class实例)。


cj 。。。
那假设以有一个类的 Class clazz=Class.forName("...")了 
那 clazz.newInstance(); 效率高 还是 new 的效率高??
   
0 请登录后投票
最后更新时间:2005-04-06
呵呵!这个我也不是很清楚。我认为应该是clazz.newInstance()快一点。因为它已经有了确切的型别了。
   
0 请登录后投票
最后更新时间:2005-04-07
楼主:
z_jordon 写道

我的理解是第一种方式,就是类的装载,连接,初始化一次性完成了。
你的这个理解是对的。

z_jordon 写道
而第二种方式,Class.forName("com.mysql.jdbc.Driver")形成一个Class的实例就相当于类的装载过程,class.newInstance()就相当于类的连接,初始化过程。
这个理解有点问题:Class.forName方法默认的情况下是类装载、链接和初始化的,相当于Class.forName(className, true, currentLoader)(其中的true和false是管是否初始化的)。如果是true的,那么装载、连接、并初始化;如果false,仅仅装载和连接。

z_jordon 写道
如果我用第二种方式生成一个类的实例,把生成的Class的实例存入一个Map中,以后再次生成这个Class的实例时从这个Map中找而不是再次Class.forName("...")有没有意义?
这个是没有意义的。因为一个类一旦被载入,就不需要再次载入了(除非你用ClassLoader去在此装载),再次的Class.forName时JVM会得到已经载入的class实例。也就是说你的这段代码的结果是true:
[code:1]
Class cla = Class.forName("java.lang.Integer");
Class cla1 = Class.forName("java.lang.Integer");
System.out.println(cla == cla1);
[/code:1]
   
0 请登录后投票
论坛首页 Java版

跳转论坛:
JavaEye推荐