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)
返回与具有给定字符串名称的类或接口(interface)相关联的 Class
对象,即它返回 test.Demo.class
对 clazz
Class
类型的变量。
然后,调用 clazz.newInstance()
创建此 Class
对象表示的类的新实例。该类被实例化为一个带有空参数列表的 new
表达式。 换句话说,这实际上等同于一个 new Demo()
和返回 Demo
的新实例。
运行这个 Demo
类会打印以下输出:
Hi!
与传统的 new
最大的区别在于 newInstance
允许实例化一个直到运行时才知道的类,从而使您的代码更具动态性。
一个典型的例子是 JDBC API,它在运行时加载执行工作所需的确切驱动程序。 EJB 容器、Servlet 容器是其他很好的例子:它们使用动态运行时加载来加载和创建在运行时之前他们不知道的组件。
其实,如果你想更进一步,看看 Ted Neward 的论文 Understanding Class.forName()我在上面的段落中解释过。
编辑(回答作为评论发布的 OP 的问题):JDBC 驱动程序的情况有点特殊。如 DriverManager 中所述Getting Started with the JDBC API章节:
(...) A
Driver
class is loaded, and therefore automatically registered with theDriverManager
, in one of two ways:
by calling the method
Class.forName
. This explicitly loads the driver class. Since it does not depend on any external setup, this way of loading a driver is the recommended one for using theDriverManager
framework. The following code loads the classacme.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 (as it should do), then it is in theDriverManager
's list of drivers and available for creating a connection.
- (...)
In both of these cases, it is the responsibility of the newly-loaded
Driver
class to register itself by callingDriverManager.registerDriver
. As mentioned, this should be done automatically when the class is loaded.
为了在初始化期间注册自己,JDBC 驱动程序通常使用这样的静态初始化 block :
package acme.db;
public class Driver {
static {
java.sql.DriverManager.registerDriver(new Driver());
}
...
}
调用 Class.forName("acme.db.Driver")
会导致 acme.db.Driver
类的初始化,从而执行静态初始化 block . Class.forName("acme.db.Driver")
确实会“创建”一个实例,但这只是(好的)JDBC 驱动程序实现方式的结果。
作为旁注,我要提一下,JDBC 4.0(自 Java 7 起作为默认包添加)和 JDBC 4.0 驱动程序的新自动加载功能不再需要所有这些。见 JDBC 4.0 enhancements in Java SE 6 .
关于java - "Class.forName()"和 "Class.forName().newInstance()"有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2092659/