有什么区别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入门

(…) ADriver类已加载,因此自动注册DriverManager,以两种方式之一:

  1. 通过调用方法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 calls DriverManager.registerDriver with that instance as the parameter (就像应该做的那样),然后在DriverManager的驱动程序列表,可用于创建连接。

  1. (…)

在这两种情况下,这都是新加载的责任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

来自: stackoverflow.com