Class.forName和new的比較

資料一:

 http://yhjhappy234.blog.163.com/blog/static/3163283220093288323624/

Class.forName(xxx.xx.xx) 返回的是一個類, .newInstance() 後才創建一個對象 Class.forName(xxx.xx.xx);的作用是要求JVM查找並加載指定的類,也就是說JVM會執行該類的靜態代碼段

Class aClass = Class.forName(xxx.xx.xx);

Object anInstance = aClass.newInstance();

Class.forName("").newInstance()返回的是object

but there is some limit for this method to create instance

that is your class constructor should no contain parameters, and you should cast the instance manually.

 

下面的例子:Class的最大作用就是實現了動態加載類,爲多態提供了很好的幫助。

class A

{

    void aa()

    {

        System.out.println ("A裏的");    

        

    }       

}

class B extends A

{

    void aa()

    {

        System.out.println ("B裏的");    

        

    }      

}

class C extends A

{

    void aa()

    {

        System.out.println ("C裏的");       

    }     

}

public class ClassDemo

{

    

    public static void main(String[] args)

    {

        ClassDemo t=new ClassDemo();

        t.show("C");

    }

    void show(String name)

    {

        try

        {

             A show=(A)Class.forName(name).newInstance();

             show.aa();

        } catch(Exception e){

             e.printStackTrace();

        }

     }

}

Class.forName()與new 的區別:從jvm的角度看,我們使用new的時候,這個要new的類可以沒有加載;

  但是使用newInstance時候,就必須保證:1、這個類已經加載;2、這個類已經連接了。而完成上面兩個步驟的正是class的靜態方法forName()方法,這個靜態方法調用了啓動類加載器(就是加載java API的那個加載器)。

  有了上面jvm上的理解,那麼我們可以這樣說,newInstance實際上是把new這個方式分解爲兩步,即,首先調用class的加載方法加載某個類,然後實例化。

  這樣分步的好處是顯而易見的。我們可以在調用class的靜態加載方法forName時獲得更好的靈活性,提供給了我們降耦的手段。

[補充:]

newInstance: 弱類型,低效率,只能調用無參構造。

new: 強類型,相對高效,能調用任何public構造。

jvm會執行靜態代碼段,你要記住一個概念,靜態代碼是和class綁定的,class裝載成功就表示執行了你的靜態代碼了。而且以後不會再走這段靜態代碼了。


資料二


來自:http://blog.csdn.net/ghost_t/article/details/5812279

在初始化一個類,生成一個實例的時候,newInstance()方法和new關鍵字除了一個是方法,一個是關鍵字外,最主要有什麼區別?它們的區別在於創建對象的方式不一樣,前者是使用類加載機制,後者是創建一個新類。那麼爲什麼會有兩種創建對象方式?這主要考慮到軟件的可伸縮、可擴展和可重用等軟件設計思想。

Java中工廠模式經常使用newInstance()方法來創建對象,因此從爲什麼要使用工廠模式上可以找到具體答案。 例如:
class c = Class.forName(“Example”);
factory = (ExampleInterface)c.newInstance();

其中ExampleInterface是Example的接口,可以寫成如下形式:
String className = "Example";
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();

進一步可以寫成如下形式:
String className = readfromXMlConfig;//從xml 配置文件中獲得字符串
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();

上面代碼已經不存在Example的類名稱,它的優點是,無論Example類怎麼變化,上述代碼不變,甚至可以更換Example的兄弟類Example2 , Example3 , Example4……,只要他們繼承ExampleInterface就可以。

從JVM的角度看,我們使用關鍵字new創建一個類的時候,這個類可以沒有被加載。但是使用newInstance()方法的時候,就必須保證:1、這個類已經加載;2、這個類已經連接了。而完成上面兩個步驟的正是Class的靜態方法forName()所完成的,這個靜態方法調用了啓動類加載器,即加載java API的那個加載器。

現在可以看出,newInstance()實際上是把new這個方式分解爲兩步,即首先調用Class加載方法加載某個類,然後實例化。 這樣分步的好處是顯而易見的。我們可以在調用class的靜態加載方法forName時獲得更好的靈活性,提供給了一種降耦的手段。

最後用最簡單的描述來區分new關鍵字和newInstance()方法的區別:
newInstance: 弱類型。低效率。只能調用無參構造。
new: 強類型。相對高效。能調用任何public構造。

Class aClass = Class.forName(xxx.xx.xx);
Object anInstance = aClass.newInstance();


Class.forName("").newInstance()返回的是object
but there is some limit for this method to create instance
that is your class constructor should no contain parameters, and you should cast the instance manually.

Class Driver{
protected static Driver current;
public static Driver getDriver(){
return current;
}
}

Class MyDriver extends Driver{
static{
Driver.current=new MyDriver();
}
MyDriver(){}
}

用時:
Class.forName("MyDriver");
Driver d=Driver.getDriver();

有的jdbc連接數據庫的寫法裏是Class.forName(xxx.xx.xx);而有一些:Class.forName(xxx.xx.xx).newInstance(),爲什麼會有這兩種寫法呢?

Class.forName(xxx.xx.xx) 返回的是一個類,
.newInstance() 後才創建一個對象

Class.forName(xxx.xx.xx);的作用是要求JVM查找並加載指定的類,也就是說JVM會執行該類的靜態代碼段

在JDBC規範中明確要求這個Driver類必須向DriverManager註冊自己,即任何一個JDBC Driver的Driver類的代碼都必須類似如下:
public class MyJDBCDriver implements Driver {
static {
DriverManager.registerDriver(new MyJDBCDriver());
}
}

所以我們在使用JDBC時只需要Class.forName(XXX.XXX);就可以了

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.

在JDBC驅動中,有一塊靜態代碼,也叫靜態初始化塊,它執行的時間是當class調入到內存中就執行(你可以想像成,當類調用到內存後就執行一個方法)。所以很多人把jdbc driver調入到內存中,再實例化對象是沒有意義的。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章