黑马程序员技术交流社区

标题: Class.forNam(String xx)的疑问 [打印本页]

作者: 小飞龙    时间: 2012-7-19 16:21
标题: Class.forNam(String xx)的疑问
Class.forName("com.mysql.jdbc.Driver");和Class.forName("com.mysql.jdbc.Driver").newInstance
();这两种方法加载数据库驱动到底有什么区别?后者看不懂?

作者: 山水游客    时间: 2012-7-19 16:35
这段代码分两种情况:1.如果是内存中有com.mysql.jdbc.Driver这个类的字节码,则获取到
                    2.如果是内存中没有com.mysql.jdbc.Driver这个类的字节码,则通过类加载器加

入到内存中,并且缓存起来,并且得到这个字节码。
                    但是上边这两种情况都只是获取到了内存中的字节码,并没有创建实例对象。

Class.forName("com.mysql.jdbc.Driver").newInstance()
是通过上边的的两种情况中的一种得到内存中的字节码,然后通过通过反射,得到这个类,以及这个类的

无参数的构造方法,然后来创建这个类的实例对象。
作者: 黑马振鹏    时间: 2012-7-19 16:43
加载数据库驱动?这个怎么理解?
作者: 王飞    时间: 2012-7-19 16:56
com.mysql.jdbc.Driver:这个类的驱动是com.mysql.jdbc.Driver自己;
com.mysql.jdbc.Driver这个类的驱动是自己的实例对象

Class.forName("com.mysql.jdbc.Driver");------这是反射方面的知识,通过传入的字符串获取相应类的字节码对象
Class.forName("com.mysql.jdbc.Driver")---(这和上面一样).newInstance---   .newInstance():是因为在这个类decom.mysql.jdbc.Driver的内部代码中把自己写成了单例(构造方法私有了),只能在内存中产生一个对象,以后用到的对象都是这个对象。
他提供了一个获取自己对象的方法,这个方法就是 newInstance();返回一个com.mysql.jdbc.Driver累对象
要用这个类的对象只能通过这个方法获取,并且获取的对象在内存中只有一个哦(这是单例模式方面的内容)

作者: rslheima    时间: 2012-7-19 16:56
Class.forName("com.mysql.jdbc.Driver");获取该类名对应的字节码文件,并加载
Class.forName("com.mysql.jdbc.Driver").newInstance();使用该类的无参构造方法创建对象
用的时候感觉两者没有什么区别
作者: 鲍霄霄    时间: 2012-7-19 17:03
本帖最后由 鲍霄霄 于 2012-7-19 17:07 编辑

有两种解释:      
一:应该是注册JDBC的驱动;
如下图中的我的程序
删除Class.forName("Com.mysql.jdbc.Driver").newInstance();后运行就可以了,你可以查找一下JDBC的书籍,也许会提到过驱动注册这一过程,但在应用中,你基本上不会用到,而仅仅是class.forname这样一句话
如果你下载一个mysql-conn***.jar,打开com.mysql.jdbc.Driver这个类,你就会看到类似的话
class Driver{
static{
DriverManager.registerDriver(new Driver());//应该没记错
}
}
很显然,它帮你注册了驱动,也许是种JDBC驱动的约定

二:Class.forName("com.mysql.jdbc.Driver").newInstance()中:1.newInstance就只是返回一个该类实例化的对象。public Driver{
public Dirver(){}
public Driver newInstance(){
return new Dirver();
}
}大致就是这样,你可以选择是直接new一个对象,还是用函数调用的方式产生一个对象。
像newInstance()这种符合工厂模式的函数是为了降低系统耦合度而设计的。具体来说,就是通过函数的方法来注入依赖值,而不是手动的new出来
看来楼主没仔细看,我那上面的代码不说明一切了么,用Class.forname就是加载它的对象而已,用newInstance也是返回他的对象。

aaa.JPG (70.71 KB, 下载次数: 20)

aaa.JPG

作者: 黄丽慧    时间: 2012-7-19 21:31
这两句代码的区别是后者要多一个实例对象.在com.mysql.jdbc.Driver这个类中,就存在一段静态代码块,当执行上面第一句代码时,如果内存没有这个字节码,那就它就会去加载这个类的字节码,而且还会去执行这个静态代码块,在这个静态代码块中调用了DriverManager.registerDriver(new Driver())方法
,所以上面第一句话也产生了实例,当然如果内存中有了这个字节码,就不会再去执行这个静代码块了。而上面第二句不仅跟第一句一样,而且,总是比第一句多一个实例对象。但如果是注册数据库驱动的话,那么最好还是用第一种方法,因为第二种方法多了一个对象,如果再用这个对象注册的话,就注册了两次了,这样内存中就多了一个没有用的对象了。有点浪费空间,而且查找驱动的时候就可能会多查找一个对象了。
作者: 陈欢    时间: 2012-7-19 22:14
本帖最后由 陈欢 于 2012-7-19 23:21 编辑

Class.forName("com.mysql.jdbc.Driver")
Class.forName("com.mysql.jdbc.Driver").newInstance()
这两句代码的区别只有一个,那就是后者要多一个实例对象.在com.mysql.jdbc.Driver这个类中,就存在一段静态代码块,当执行上面第一句代码时,如果内存没有这个字节码,那就它就会去加载这个类的字节码,而且还会去执行这个静态代码块,在这个静态代码块中调用了DriverManager.registerDriver(new Driver())方法
,所以上面第一句话也产生了实例,当然如果内存中有了这个字节码,就不会再去执行这个静代码块了。
作者: 陈欢    时间: 2012-7-19 23:15
本帖最后由 陈欢 于 2012-7-19 23:20 编辑

每个人都总结了一点 ,好像就很全面了{:soso_e100:}

作者: 武庆东    时间: 2012-7-19 23:21
通过Class.forName()f方法实例化Class对象之后,直接强调用newInstance()方法既可以根据传入的完整“包.类”名称的方式进行对象的实例化操作,完全取代new的操作方式
作者: 柳雷    时间: 2012-7-20 00:20
newInstance就只是返回一个该类实例化的对象。
public Driver{
public Dirver(){}
public Driver newInstance(){
return new Dirver();
}
}大致就是这样,你可以选择是直接new一个对象,还是用函数调用的方式产生一个对象。
像newInstance()这种符合工厂模式的函数是为了降低系统耦合度而设计的。具体来说,就是通过函数的方法来注入依赖值,而不是手动的new出来。





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2