先通过我们一个熟悉的例子来说明:
使用JDBC时,我们都会很自然得使用下列语句:
1Class.forName("com.mysql.jdbc.Driver");
2Stringurl="jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8";
3Stringuser="";
4Stringpsw="";
5Connectioncon=DriverManager.getConnection(url,user,psw);
一定要有这一句吗?不是的,我们完全可以用这样一句代替它:
1com.mysql.jdbc.Driverdriver=newcom.mysql.jdbc.Driver();
2//or:
3//newcom.mysql.jdbc.Driver();
4Stringurl="jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8";
5Stringuser="";
6Stringpsw="";
7Connectioncon=DriverManager.getConnection(url,user,psw);
大家可能都看出个大概来了,我们只需要在调用DriverManager的getConnection方法之前,保证相应的Driver类已经被加载到 jvm中,并且完成了类的初始化工作就行了,而具体是怎样实现这个功能却是没有讲究的。上面两种方法都可以实现这个功能,因此程序可以正常运行。注意了,如果我们进行如下操作,程序是不能正常运行的,因为这样仅仅使Driver类被装载到jvm中,却没有进行相应的初始化工作。
我们都知道JDBC是使用Bridge模式进行设计的,DriverManager就是其中的Abstraction,java.sql.Driver是 Implementor,com.mysql.jdbc.Driver是Implementor的一个具体实现(请参考GOF的Bridge模式的描述)。大家注意了,前一个Driver是一个接口,后者却是一个类,它实现了前面的Driver接口。
Bridge模式中,Abstraction(DriverManager)是要拥有一个Implementor(Driver)的引用的,但是我们在使用过程中,并没有将Driver对象注册到DriverManager中去啊,这是怎么回事呢?jdk文档对Driver的描述中有这么一句:
When a Driver class is loaded, it should create an instance of itself and register it with the DriverManager
哦,原来是com.mysql.jdbc.Driver在装载完后自动帮我们完成了这一步骤。源代码是这样的:
packagecom.mysql.jdbc
publicclassDriverextendsNonRegisteringDriverimplementsjava.sql.Driver {
//~Staticfields/initializers
//---------------------------------------------//
//RegisterourselveswiththeDriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(newDriver());
}catch(SQLExceptionE) {
thrownewRuntimeException("Can'tregisterdriver!");
}
}
//~Constructors
//-----------------------------------------------------------
*ConstructanewdriverandregisteritwithDriverManager
*
*@throwsSQLException
*ifadatabaseerroroccurs.
*/
publicDriver()throwsSQLException {
//RequiredforClass.forName().newInstance()
}
}
我的话:看出来了吧,在java文件进行编译时,它能确保语法的正确,却不能知道,载入内存中的是哪个类,在运行时jvm将对应的.class文件载入内存中,并可以调用类的方法。
专业的解释是:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
又如:(第二例)
其实这种反射机制,在远程调用中使用的最多,因为 本地文件在编译时并不能确定从网络上传输过来的是什么类,和他有什么方法,只有运行时通过.class文件才能知道。
ProductEntity p = em.find(ProductEntity.class,productId);
这是实体管理器从本地查找实体类,又如jndi,可能都涉及到reflection机制。
发表评论
-
java面试总结(1)——基础知识
2012-07-05 15:54 8601、什么是多态? 多态,父类的引用指向子类的对象,使父类的引 ... -
递归-组合(用背包问题解)
2011-04-01 21:23 745求指定数据的组合,这里的指定数据用一个数组模拟所有可以选择 ... -
Servlet和JSP的线程安全问题
2011-03-25 10:50 766不要定义servlet的类变量,不要使用jsp中的s ... -
Java同步机制浅谈―synchronized
2011-03-25 10:20 984Java对多线程的支持 ... -
代码复用的规则
2011-03-24 17:25 643李炜 北京杰合伟业软件公司产品技术部经理2001 年 7 ... -
java多进程——Java Multiple process (PID)
2011-03-24 10:48 1533Java的多进程运行模式分析 一般我们在java中运行其 ... -
用JSP实现假分页
2008-08-08 10:29 7331.使用MySql数据库建一个表,并添加记录: -- 删除表 ... -
用MVC模式实现真分页
2008-08-23 21:01 519·我们在之前代码上实现一个搜索框 输入查询关键字:< ... -
位运算符
2008-08-24 19:35 337Java 定义的位运算(bitwise operators ) ... -
struts高级技术——解决重复提交和上传文件
2008-08-24 19:44 431·解决重复提交的工具——Token令牌<?xml:nam ... -
从class.forName()说java中的reflection(反射/映像)
2008-09-21 21:19 530先通过我们一个熟悉的例子来说明: 使用JDBC时,我们都会很 ... -
eclipse 自动补全的设置,不用按 alt-/ 了
2011-03-23 11:07 697偶然间看到了这个,或许有和我一样不喜欢按 alt-/ 兄弟用得 ... -
用JSP实现假分页
2008-08-08 10:29 13411.使用MySql数据库建一个表,并添加记录: -- 删除表 ... -
用MVC模式实现真分页
2008-08-23 21:01 1153·我们在之前代码上实现一个搜索框 输入查询关键字:< ... -
位运算符
2008-08-24 19:35 748Java 定义的位运算(bitwise operators ) ... -
java排序大全
2008-08-24 19:42 646java排序大全 插入排序: packag ... -
struts高级技术——解决重复提交和上传文件
2008-08-24 19:44 835·解决重复提交的工具——Token令牌<?xml:nam ...
相关推荐
NULL 博文链接:https://listen-raining.iteye.com/blog/1894456
Class.forName(xxx.xx.xx) 返回的是一个类,但Class.forName方法的作用到底...下面这篇文章就来给大家详细介绍了关于java中Class.forName方法的作用,文中介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
Class.forName(xxx.xx.xx) 返回的是一个类 Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
在Java的反射中,Class.forName和ClassLoader的区别共4页.pdf.zip
class.forname的作用.doc 详细解析抽象类和接口的区别.doc
NULL 博文链接:https://wuaner.iteye.com/blog/1009134
介绍了java中Class.forName的作用,有需要的朋友可以参考一下
并且只有调用了newInstance()方法采用调用构造函数,创建类的对象看下Class.forName()源码//Class.forName(String c
对SPI,理论联系实际的理解
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); //Sql Server7.0/2000数据库 Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); //DB2数据库 Class....
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb"; //mydb为数据库 String user="sa"; String password=...
c = Class.forName("java.lang.String"); System.out.println("package " + c.getPackage().getName() + ";\n"); System.out.print(Modifier.toString(c.getModifiers())); System.out.print(" class " ...
Spire.Barcode for JAVA 是一款Java条形码组件,开发人员可以使用它在Java应用程序中简洁快速地生成和识别多种一维和二维条码。下载以后解压缩,然后从lib文件夹下导入Spire.Barcode.jar包到你的Java应用程序中即可...
JAVA 程序 源代码 import java.applet.*;import java.awt.*
使用class.forname利用反射创建类,然后再获取属性,方法,体现反射应用
java连接各种数据库的驱动 jar包 orale: Class.forName("oracle.jdbc.driver.OracleDriver"); mysql:Class.forName("com.mysql.jdbc.Driver"); access:Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); sqlsever:...
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); //Sql Server7.0/2000 数据库 Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); //DB2 数据库 Class.froName(...
Java中 Class.forName()_newInstance()_New_三者区别。
Class ownerClass = Class.forName(className) :首先得到这个类的Class。 Field field = ownerClass.getField(fieldName):和上面一样,通过Class得到类声明的属性。 Object property = field.get(ownerClass) :...