“Class.forName()”和“Class.forName().newInstance()”之间有什么区别?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (30)

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();
    }
}

运行这个Demo类输出如下:

Hi!

与传统new那是newInstance允许实例化一个直到运行时才知道的类,从而使代码更加动态。

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

  1. 通过调用方法Class.forName...。这将显式地加载驱动程序类。由于它不依赖于任何外部设置,因此建议使用这种加载驱动程序的方式使用DriverManager框架。下面的代码加载类acme.db.Driver* Class.forName(“acme.db.driver”);如果acme.db.Driver已经写入,以便加载它将导致创建实例,并调用DriverManager.registerDriver以该实例作为参数(正如它应该做的那样),然后它在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驱动程序的结果。

另外,我要指出的是,JDBC4.0(从Java 7开始作为默认包添加)和JDBC4.0驱动程序的新自动加载特性不再需要这些功能了。

用户回答回答于

forName()为您提供了类对象,这对于反射非常有用。这个对象所拥有的方法是由Java定义的,而不是由编写类的程序员定义的。每个班级都是一样的。对该类调用newInstance()将为您提供该类的实例(即调用Class.forName("ExampleClass").newInstance()它相当于调用new ExampleClass()),可以在该方法上调用类定义的方法,访问可见字段等。

扫码关注云+社区