首先:
New = Class.forName("pacage.A").newInstance();
new是关键字,直接创建对象。
Class.forName()是一个方法,要求JVM查找并加载指定的类,类装载到虚拟机上之后,静态方法和静态块中的处理被执行。
这时候还没有创建对象。newInstance()是创建对象。
我们最常用的jdbc, 经常会用Class.forName来加载数据库驱动。
例子:
jdbc接口中,会存在各种数据库的驱动,不在在接口中写死,一般都写在配置文件里,
所以需要我们调用的时候通过Class.forName来加载驱动。这时候不需要创建对象,所有没有调用newInstance()。
Class.forName(类名) jvm动态的加载一个类。
Class.forName(类名).newInstance() 调用类的无参构造方法返回的是Object对象,需要强转为指定类型。
new 是一个关键字,调用类的构造方法(可以无参的、有参的),返回一个类的对象。
例如
EgClass egClass=(EgClass)Class.forName(“EgClass类名”).newInstance();
问题:为什么有的类使用的时候只需要Class.forName(),不需要Class.forName().newInstance()?如加载数据库驱动时?
因为需要的内容写在了类的静态方法中了。在类的加载过程中,类的静态方法中的代码已经执行过了,不需要再实例化了。
例如:
ClassA {
static{
相关内容
}
}
也许一个演示如何使用这两种方法的示例将有助于更好地理解事物。因此,请考虑以下类:
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容器是其他一些很好的例子:它们使用动态运行时加载来加载和创建运行时之前不知道的组件。
- 通过调用方法
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()
),可以在该方法上调用类定义的方法,访问可见字段等。