有什么区别Class.forName()
和Class.forName().newInstance()
?
我不了解显着差异(我读过一些有关它们的东西!)。请你帮助我好吗?
答案
也许一个例子说明如何使用两种方法都会帮助您更好地理解事物。因此,考虑以下课程:
package test;
public class Demo {
public Demo() {
System.out.println("Hi!");
}
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("test.Demo");
Demo demo = (Demo) clazz.newInstance();
}
}
正如其Javadoc中解释的那样Class.forName(String)
返回Class
与给定字符串名称相关联的对象或接口 即它返回test.Demo.class
受影响的clazz
类型变量Class
。
然后,调用clazz.newInstance()
创建一个由此表示的类的新实例Class
目的。该课程是由new
带有空参数列表的表达式。 换句话说,这实际上等同于new Demo()
并返回一个新实例Demo
。
并运行这个Demo
因此,类打印以下输出:
Hi!
与传统的最大不同new
就是它newInstance
允许在运行时实例化您不认识的类,使您的代码更加动态。
一个典型的示例是JDBC API,它在运行时加载执行工作所需的确切驱动程序。EJBS容器,Servlet容器是其他好的示例:它们使用动态运行时加载来加载并创建组件,在运行时不知道任何东西。
实际上,如果您想走得更远,请看一下TED Neward Paper了解class.forname()我在上面的段落中解释了。
EDIT (回答从OP发表的评论中的问题):JDBC驱动程序的情况有点特别。如在Drivermanager章节JDBC API入门:
(…) A
Driver
类已加载,因此自动注册DriverManager
,以两种方式之一:
通过调用方法
Class.forName
。这明确加载了驱动程序类。由于它不取决于任何外部设置,因此加载驱动程序的这种方式是建议使用的驱动程序DriverManager
框架。以下代码加载类acme.db.Driver
:Class.forName("acme.db.Driver");
If
acme.db.Driver
has been written so that loading it causes an instance to be created and also callsDriverManager.registerDriver
with that instance as the parameter (就像应该做的那样),然后在DriverManager
的驱动程序列表,可用于创建连接。
- (…)
在这两种情况下,这都是新加载的责任
Driver
通过打电话给自己注册的课程DriverManager.registerDriver
。如前所述,加载课时应自动完成此操作。
在初始化期间注册自己,JDBC驱动程序通常使用这样的静态初始化块:
package acme.db;
public class Driver {
static {
java.sql.DriverManager.registerDriver(new Driver());
}
...
}
打电话Class.forName("acme.db.Driver")
导致初始化acme.db.Driver
类,从而执行静态初始化块。和Class.forName("acme.db.Driver")
确实会"创建"一个实例,但这只是如何实现(良好的)JDBC驱动程序的结果。
附带说明,我提到的是,JDBC 4.0不再需要所有这些(自Java 7以来添加为默认软件包)和JDBC 4.0驱动程序的新自动加载功能。看JDBC 4.0 Java SE的增强6。