JAVA中Class.forName的含义
2013-10-17 00:04
302 查看
Class.forName("xxx.xx.xx");返回的是一个类(java.lang.Class)对象。
*.newInstance();后才创建一个普通Java对象。
Class.forName("xxx.xx.xx")的作用是:要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。
Class.forName("xxx.xx.xx").newInstance()返回的是Object对象。
but there is some limit for this method to create instance,
that is your class constructor should no contain parameters, and you should cast the instance manually.
即,使用该方法必须存在无参构造函数,否则会报如下异常:
----------------------------------------------
使用时:
Class.forName("MyDriver");//导致执行MyDriver的静态代码块
Driver d = Driver.getDriver();
有的jdbc连接数据库的写法里是Class.forName(xxx.xx.xx);而有的这么写:Class.forName(xxx.xx.xx).newInstance();
这两种有什么区别呢?
数据库驱动一般都含有如下代码:
public class MyJDBCDriver implements Driver {
static {
DriverManager.registerDriver(new MyJDBCDriver());
}
}
即,向DriverManager数据库驱动管理器注册该驱动。只要能让注册方法执行的任何写法都是可以的。
所以我们在使用JDBC时只需要
Class.forName(xxx.xx.xx); 就可以了。没有必要再生成一个我们不会使用的对象。
当然最新版本的数据库驱动中使用了Service Provider Interface技术,即不再需要加载驱动的代码。
下面给一个例子:Class的最大作用就是实现了动态加载类,为多态提供了很好的帮助。
*.newInstance();后才创建一个普通Java对象。
Class.forName("xxx.xx.xx")的作用是:要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。
Class.forName("xxx.xx.xx").newInstance()返回的是Object对象。
but there is some limit for this method to create instance,
that is your class constructor should no contain parameters, and you should cast the instance manually.
即,使用该方法必须存在无参构造函数,否则会报如下异常:
java.lang.InstantiationException: Demo at java.lang.Class.newInstance(Class.java:427) at T.test1(T.java:24) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) Caused by: java.lang.NoSuchMethodException: Demo.<init>() at java.lang.Class.getConstructor0(Class.java:3082) at java.lang.Class.newInstance(Class.java:412) ... 23 more
----------------------------------------------
Class Driver{ protected static Driver current; public static Driver getDriver(){ return current; } } Class MyDriver extends Driver{ static{ Driver.current=new MyDriver(); } MyDriver(){} }
使用时:
Class.forName("MyDriver");//导致执行MyDriver的静态代码块
Driver d = Driver.getDriver();
有的jdbc连接数据库的写法里是Class.forName(xxx.xx.xx);而有的这么写:Class.forName(xxx.xx.xx).newInstance();
这两种有什么区别呢?
数据库驱动一般都含有如下代码:
public class MyJDBCDriver implements Driver {
static {
DriverManager.registerDriver(new MyJDBCDriver());
}
}
即,向DriverManager数据库驱动管理器注册该驱动。只要能让注册方法执行的任何写法都是可以的。
所以我们在使用JDBC时只需要
Class.forName(xxx.xx.xx); 就可以了。没有必要再生成一个我们不会使用的对象。
当然最新版本的数据库驱动中使用了Service Provider Interface技术,即不再需要加载驱动的代码。
下面给一个例子:Class的最大作用就是实现了动态加载类,为多态提供了很好的帮助。
import org.junit.Test; class A { public void fun() { System.out.println("A"); } } class B extends A { @Override public void fun() { System.out.println("B"); } } class C extends A { @Override public void fun() { System.out.println("C"); } } public class T { @Test public void test1() throws ClassNotFoundException, IllegalAccessException, InstantiationException { A a = (A) Class.forName("C").newInstance(); a.fun(); } }
相关文章推荐
- [HKEY_LOCAL_MACHINE\init]键值的含义
- [Python]网络爬虫(一):抓取网页的含义和URL基本构成
- Linux编程下EAGAIN和EINTR宏的含义及处理
- HTTP 请求返回代码含义
- Linux中变量$#,$@,$0,$1,$2,$*,$$,$?的含义
- Layout_weight的含义
- linux 关键字后所跟数字的含义
- xcode 左边导航栏中,类文件后面的标记“A”,"M","?"……等符号的含义???
- Linux chmod命令及权限含义
- Windows Media Player 网页播放器 参数含义
- Oracle db中 CONNECT role的含义
- Linux--Shell中变量 $# $0 $1 $2 $@ $* $$ $? 的含义
- 主板BIOS报警信号含义一览
- shell 编程之2>&1含义
- java中volatile关键字的含义
- [x264]int16_t (*mv[2])[2]的含义
- struct sockaddr_nl 结构体 由来、含义以及使用——获取Linux路由表
- 以双斜杠//开头的URL的含义
- DDR2-667/800的含义
- PO、POJO、BO、DTO等在项目中的含义(整理)