“Class.forName()"和“Class.forName()"有什么区别?和“Class.forName().newInstance()"? [英] What is the difference between "Class.forName()" and "Class.forName().newInstance()"?

查看:56
本文介绍了“Class.forName()"和“Class.forName()"有什么区别?和“Class.forName().newInstance()"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Class.forName()Class.forName().newInstance() 有什么区别?

我不明白其中的显着差异(我已经阅读了一些关于它们的内容!).你能帮我吗?

I do not understand the significant difference (I have read something about them!). Could you please help me?

推荐答案

也许一个演示如何使用这两种方法的示例将帮助您更好地理解事物.因此,请考虑以下类:

Maybe an example demonstrating how both methods are used will help you to understand things better. So, consider the following class:

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,它影响 Class 类型的 clazz 变量.

As explained in its javadoc, calling Class.forName(String) returns the Class object associated with the class or interface with the given string name i.e. it returns test.Demo.class which is affected to the clazz variable of type Class.

然后,调用 clazz.newInstance() 创建由这个Class 对象表示的类的新实例.该类被实例化为一个带有空参数列表的 new 表达式. 换句话说,这里实际上相当于一个 new Demo() 和返回 Demo 的新实例.

Then, calling clazz.newInstance() creates a new instance of the class represented by this Class object. The class is instantiated as if by a new expression with an empty argument list. In other words, this is here actually equivalent to a new Demo() and returns a new instance of Demo.

并运行这个 Demo 类因此打印以下输出:

And running this Demo class thus prints the following output:

Hi!

与传统 new 的最大区别在于 newInstance 允许实例化一个您直到运行时才知道的类,从而使您的代码更具动态性.

The big difference with the traditional new is that newInstance allows to instantiate a class that you don't know until runtime, making your code more dynamic.

一个典型的例子是 JDBC API,它在运行时加载执行工作所需的确切驱动程序.EJB 容器、Servlet 容器是其他很好的例子:它们使用动态运行时加载来加载和创建在运行时之前不知道的组件.

A typical example is the JDBC API which loads, at runtime, the exact driver required to perform the work. EJBs containers, Servlet containers are other good examples: they use dynamic runtime loading to load and create components they don't know anything before the runtime.

实际上,如果你想更进一步,看看 Ted Neward 的论文 理解 Class.forName() 我在上面的段落中释义.

Actually, if you want to go further, have a look at Ted Neward paper Understanding Class.forName() that I was paraphrasing in the paragraph just above.

EDIT(回答作为评论发布的 OP 中的一个问题):JDBC 驱动程序的情况有点特殊.如 DriverManager 章节所述JDBC API 入门:

EDIT (answering a question from the OP posted as comment): The case of JDBC drivers is a bit special. As explained in the DriverManager chapter of Getting Started with the JDBC API:

(...) 一个 Driver 类被加载,并且因此自动注册使用 DriverManager,在两个之一方法:

(...) A Driver class is loaded, and therefore automatically registered with the DriverManager, in one of two ways:

  1. 通过调用方法Class.forName.这显式加载驱动程序类.由于它不依赖于任何外部设置,这样推荐加载驱动程序一种用于使用 DriverManager框架.以下代码加载类 acme.db.Driver:

  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");

如果 acme.db.Driver 已经写入,加载它会导致要创建的实例并调用DriverManager.registerDriver 与实例作为参数(因为它应该做),那么它在DriverManager 的驱动程序列表和可用于创建连接.

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. (...)

在这两种情况下,新加载的Driver 类有责任通过调用DriverManager.registerDriver 来注册自己.如前所述,这应该在加载类时自动完成.

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 驱动程序通常使用这样的静态初始化块:

To register themselves during initialization, JDBC driver typically use a static initialization block like this:

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 驱动程序实现方式的结果.

Calling Class.forName("acme.db.Driver") causes the initialization of the acme.db.Driver class and thus the execution of the static initialization block. And Class.forName("acme.db.Driver") will indeed "create" an instance but this is just a consequence of how (good) JDBC Driver are implemented.

作为旁注,我要提到 JDBC 4.0(自 Java 7 以来作为默认包添加)和 JDBC 4.0 驱动程序的新自动加载功能不再需要所有这些.请参阅 Java 中的 JDBC 4.0 增强功能SE 6.

As a side note, I'd mention that all this is not required anymore with JDBC 4.0(added as a default package since Java 7) and the new auto-loading feature of JDBC 4.0 drivers. See JDBC 4.0 enhancements in Java SE 6.

这篇关于“Class.forName()"和“Class.forName()"有什么区别?和“Class.forName().newInstance()"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆