您的位置:首页 > 编程语言 > Java开发

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.
即,使用该方法必须存在无参构造函数,否则会报如下异常:

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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: