|
锁定老贴子 主题:请问如何理解类的装载,连接,初始化?
精华帖 (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("...")有没有意义? 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2005-04-06
以后可以不用forName(...)方法再生成该类型的Class实例。除非你需要生成不同型别的实例。一个Class的实例代表一种型别。
|
|
| 返回顶楼 | |
|
最后更新时间:2005-04-06
那我对第一种方式的理解有没有错?就是说如果new 一个对象就相当于一次性的完成装载,连接,初始化的过程,难道说每new一个对象都需要执行一次装载的过程?
|
|
| 返回顶楼 | |
|
最后更新时间: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. |
|
| 返回顶楼 | |
|
最后更新时间:2005-04-06
楼上楼下不要跑题.
我也不明白为什么用方法2来写 |
|
| 返回顶楼 | |
|
最后更新时间: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] |
|
| 返回顶楼 | |
|
最后更新时间:2005-04-06
两个forName(...)方法返回的class实例的reference都是一样的。因为它们的型别是一样的,当然是true啊!一个型别在被装载的时候就产生一个Class实例。(包括基本类型int,double,等等都有对应它们型别的Class实例)。
|
|
| 返回顶楼 | |
|
最后更新时间:2005-04-06
kofandkingmax 写道 两个forName(...)方法返回的class实例的reference都是一样的。因为它们的型别是一样的,当然是true啊!一个型别在被装载的时候就产生一个Class实例。(包括基本类型int,double,等等都有对应它们型别的Class实例)。
cj 。。。 那假设以有一个类的 Class clazz=Class.forName("...")了 那 clazz.newInstance(); 效率高 还是 new 的效率高?? |
|
| 返回顶楼 | |
|
最后更新时间:2005-04-06
呵呵!这个我也不是很清楚。我认为应该是clazz.newInstance()快一点。因为它已经有了确切的型别了。
|
|
| 返回顶楼 | |
|
最后更新时间: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] |
|
| 返回顶楼 | |









