java - "Class.forName()"和 "Class.forName().newInstance()"有什么区别?

标签 java class object instantiation

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.classclazz 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 the DriverManager, in one of two ways:

  1. 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 the DriverManager framework. The following code loads the class 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 calls DriverManager.registerDriver with that instance as the parameter (as it should do), then it is in the DriverManager's list of drivers and available for creating a connection.

  1. (...)

In both of these cases, it is the responsibility of the newly-loaded Driver class to register itself by calling DriverManager.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/

相关文章:

c++ - WxWidgets - 从主文件以外的文件更改 texbox

c++ - 类成员 - 对于外部世界来说是 const,对于类来说是非常量

oop - 在面向对象编程中,我们什么时候需要抽象?

java - maven 中 WebProject 的依赖

java - 如何从 openCV android 中的 Byte[] 获取 Mat 对象?

php - 如何在不创建类的实例的情况下获取类的完整命名空间?

令人头疼的 Javascript 数组排序

java - 如何使用Java的BufferedReader和InputStreamReader读取文件?

java - 使用 Saxon 处理 JIRA 模块中的 XPath

ios - 如何从 JSON 创建对象集合