Class.forName()用法 Class.forName()、Class.forName().newInstance() 、New 三者区别!

主要功能
Class.forName(xxx.xx.xx)返回的是一个类。
Class.forName(xxx.xx.xx)的做用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。

下面,经过解答如下三个问题的来详细讲解下Class.forName()的用法。
一.何时用Class.forName()?
先来个热身,给你一个字符串变量,它表明一个类的包名和类名,你怎么实例化它?你第一想到的确定是new,可是注意一点:
A a = (A)Class.forName(“pacage.A”).newInstance();
这和你 A a = new A(); 是同样的效果。html

如今言归正传。
动态加载和建立Class 对象,好比想根据用户输入的字符串来建立对象时须要用到:
String str = “用户输入的字符串” ;
Class t = Class.forName(str);
t.newInstance();java

在初始化一个类,生成一个实例的时候,newInstance()方法和new关键字除了一个是方法,一个是关键字外,最主要有什么区别?数据库

它们的区别在于建立对象的方式不同,前者是使用类加载机制,后者是建立一个新类。jvm

那么为何会有两种建立对象方式?这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。函数

Java中工厂模式常用newInstance()方法来建立对象,所以从为何要使用工厂模式上能够找到具体答案。 例如:
class c = Class.forName(“Example”);
factory = (ExampleInterface)c.newInstance();post

其中ExampleInterface是Example的接口,能够写成以下形式:
String className = “Example”;
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();ui

进一步能够写成以下形式:
String className = readfromXMlConfig;//从xml 配置文件中得到字符串
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();编码

上面代码已经不存在Example的类名称,它的优势是,不管Example类怎么变化,上述代码不变,甚至能够更换Example的兄弟类Example2 , Example3 , Example4……,只要他们继承ExampleInterface就能够。url

从JVM的角度看,咱们使用关键字new建立一个类的时候,这个类能够没有被加载。可是使用newInstance()方法的时候,就必须保证:
一、这个类已经加载;
二、这个类已经链接了。
而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 java API的那个加载器。设计

如今能够看出,newInstance()其实是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,而后实例化。

这样分步的好处是显而易见的。咱们能够在调用class的静态加载方法forName时得到更好的灵活性,提供给了一种降耦的手段。

二.new 和Class.forName()有什么区别?
其实上面已经说到一些了,这里来作个总结:
首先,newInstance( )是一个方法,而new是一个关键字;
其次,Class下的newInstance()的使用有局限,由于它生成对象只能调用无参的构造函数,而使用 new关键字生成对象没有这个限制。
简言之:
newInstance(): 弱类型,低效率,只能调用无参构造。
new: 强类型,相对高效,能调用任何public构造。
Class.forName(“”)返回的是类。
Class.forName(“”).newInstance()返回的是object 。
三.为何在加载数据库驱动包的时候有用的是Class.forName( ),却没有调用newInstance( )?
在Java开发特别是数据库开发中,常常会用到Class.forName( )这个方法。
经过查询Java Documentation咱们会发现使用Class.forName( )静态方法的目的是为了动态加载类。
一般编码过程当中,在加载完成后,通常还要调用Class下的newInstance( )静态方法来实例化对象以便操做。所以,单使用Class.forName( )是动态加载类是没有用的,其最终目的是为了实例化对象。

相关英文参考文献以下:
we just want to load the driver to jvm only, but not need to user the instance of driver,
so call Class.forName(xxx.xx.xx) is enough, if you call Class.forName(xxx.xx.xx).newInstance(),
the result will same as calling Class.forName(xxx.xx.xx),
because Class.forName(xxx.xx.xx).newInstance() will load driver first,
and then create instance, but the instacne you will never use in usual,
so you need not to create it.

========================== 华丽的分割线 =============================

Class.forName()、Class.forName().newInstance() 、New 三者区别!

终于明白为何加载数据库驱动只用Class.forName()了!!困扰了我2个小时!!但愿我写的这个东西对各位有所帮助。

   
   在Java开发特别是数据库开发中,常常会用到Class.forName( )这个方法。
经过查询Java Documentation咱们会发现使用Class.forName( )静态方法的目的是为了动态加载类。
在加载完成后,通常还要调用Class下的newInstance( )静态方法来实例化对象以便操做。所以,单单使用Class.forName( )是动态加载类是没有用的,其最终目的是为了实例化对象。 
   这里有必要提一下就是Class下的newInstance()和new有什么区别?,首先,newInstance( )是一个方法,而new是一个关键字,其次,Class下的newInstance()的使用有局限,由于它生成对象只能调用无参的构造函数,而使用 new关键字生成对象没有这个限制。 
   好,到此为止,咱们总结以下: 
   Class.forName("")返回的是类 
   Class.forName("").newInstance()返回的是object 
   有数据库开发经验朋友会发现,为何在咱们加载数据库驱动包的时候有的却没有调用newInstance( )方法呢?即有的jdbc链接数据库的写法里是Class.forName(xxx.xx.xx);而有一 些:Class.forName(xxx.xx.xx).newInstance(),为何会有这两种写法呢?
   刚才提到,Class.forName("");的做用是要求JVM查找并加载指定的类,若是在类中有静态初始化器的话,JVM必然会执行该类的静态代码 段。而在JDBC规范中明确要求这个Driver类必须向DriverManager注册本身,即任何一个JDBC Driver的 Driver类的代码都必须相似以下:
  public class MyJDBCDriver implements Driver {
   static {
     DriverManager.registerDriver(new MyJDBCDriver());
  }
  }
 既然在静态初始化器的中已经进行了注册,因此咱们在使用JDBC时只须要Class.forName(XXX.XXX);就能够了。
 
贴出Proxool 链接池的静态初始化方法:
public class ProxoolDriver implements Driver {

    private static final Log LOG = LogFactory.getLog(ProxoolDriver.class);

    static {
        try {
            DriverManager.registerDriver(new ProxoolDriver());
        } catch (SQLException e) {
            System.out.println(e.toString());
        }
    }
}