2012-06-08 49 views

回答

138

而言,我不會對它們進行比較的優點/缺點,因爲他們有不同的目的,很少有一個「選擇」,以使這兩個。

  • a.getClass()返回運行時類型a。即的之間,如果你有A a = new B();然後a.getClass()將返回B類。

  • A.class計算結果爲A靜態,並且被用於通常與反射其他目的。

在性能方面,有可能一個可測量的差異,但我不會說什麼,因爲它到底是JVM和/或編譯器相關的。


此主題已被改寫爲文章here

+0

怎麼樣'A.class.getClass()'? – user1870400

+0

這會給你表示'A.class'對象的'Class'對象,它又是'java.lang.Class'的一個實例。 – aioobe

30

它們在哪裏可以使用它們實際上是不同的。 A.class在編譯時工作,而a.getClass()需要A類型的實例並在運行時工作。

也可能存在性能差異。雖然A.class可以由編譯器解析,因爲它知道A的實際類型,a.getClass()是在運行時發生的虛擬方法調用。

作爲參考,一個編譯器靶向字節碼通常發射以下指令,用於Integer.getClass()

aload_1 
invokevirtual #3; //Method java/lang/Object.getClass:()Ljava/lang/Class; 

Integer.class以下:

//const #3 = class #16; // java/lang/Integer 

ldc_w #3; //class java/lang/Integer 

前者將典型地涉及一個虛擬方法分派,因此大概需要更長的時間來執行。然而,這與最終的JVM相關。

+1

[1]在技術上Java語言規範並沒有提到任何常量池... – aioobe

+0

@aioobe:我想你是對的,這就是爲什麼我檢查了由Sun JDK生成的字節碼。 –

+1

......從技術上說,它也不提供權威的答案,因爲在語義方面,Java語言規範甚至沒有提及字節碼。 – aioobe

5

低於

a.getClass()!= A.class看看例子,即是不是一個實例,但一個匿名子類的

a.getClass() 需要類型的實例的

1

有是我想補充的一個區別。讓我們假設你有一個類構造函數,如下所示,它帶有一個需要Class對象的超類。無論何時創建子類對象,都應該將子類的類對象傳遞給超類。下面的代碼不會編譯,因爲您無法在構造函數中調用實例方法。在這種情況下,如果您將myObject.getClass()替換爲MyClass.class。它將完美運行。

Class MyClass 
{ 
    private MyClass myObject = new MyClass(); 
    public MyClass() 
    { 
     super(myObject.getClass()); //error line compile time error 
    } 
} 
+2

具有與同一類的實例變量相同的類的實例....您將在遞歸創建對象時耗盡堆空間。 –

4

使用a.getClass當你有一個類/類型的實例,你想得到它的確切類型。而當您有type可用並且您想要創建它的實例時使用a.class
另外getClass()返回實例的運行時類型,而.class在編譯時計算。
考慮到getClass().class的性能,.classgetClass()具有更好的性能。
實施例:

public class PerfomanceClass { 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 

     long time=System.nanoTime(); 
     Class class1="String".getClass(); 
     class1="String".getClass(); 
     class1="String".getClass(); 
     class1="String".getClass(); 

     System.out.println("time (getClass()) :"+(System.nanoTime()-time)+" ns");  


     long time2=System.nanoTime(); 
     Class class2=String.class; 
     class2=String.class; 
     class2=String.class; 
     class2=String.class; 

     System.out.println("time (.class):"+(System.nanoTime()-time2)+" ns"); 
    } 

} 

輸出:

time (getClass()) : 79410 ns 
time (.class)  : 8032 ns 
1

有趣的是在上面的例子中提到的在性能上的差異,似乎與其他原因。使用3個不同的職業,平均性能將幾乎相同:

import java.util.LinkedHashMap; 
public class PerfomanceClass { 

public static void main(String[] args) { 

    long time = System.nanoTime(); 
    Class class1 = "String".getClass(); 
    Class class11 = "Integer".getClass(); 
    Class class111 = "LinkedHashMap".getClass(); 

    System.out.println("time (getClass()) :" + (System.nanoTime() - time) + " ns"); 

    long time2 = System.nanoTime(); 
    Class class2 = String.class; 
    Class class22 = Integer.class; 
    Class class222 = LinkedHashMap.class; 

    System.out.println("time (.class):" + (System.nanoTime() - time2) + " ns"); 
} } 

輸出將是這樣的:

time (getClass()) :23506 ns 
time (.class):23838 ns 

並切換調用的順序,甚至會導致getClass()速度更快。

import java.util.LinkedHashMap; 

public class PerfomanceClass { 

public static void main(String[] args) { 
    long time2 = System.nanoTime(); 
    Class class2 = LinkedHashMap.class; 

    System.out.println("time (.class):" + (System.nanoTime() - time2) + " ns"); 

    long time = System.nanoTime(); 
    Class class1 = "LinkedHashMap".getClass(); 

    System.out.println("time (getClass()) :" + (System.nanoTime() - time) + " ns"); 
}} 

輸出:

time (.class):33108 ns 
time (getClass()) :6622 ns 
+0

「使用3個不同的類」。但在getClass()部分中,您並未使用3個不同的類。這些都是String,因此getClass將爲所有實例返回java.lang.String。 – John

相關問題