getclass()學過Python的同學肯定很熟悉,是不是有點像__dict__ method?其實這個自省,JAVA中叫做反射,可以理解為在運行時期擷取物件類型資訊的操作,兩者幾乎相同。傳統的編程方法要求程式員在編譯階段決定使用的類型,但是在反射的協助下,編程人員可以動態擷取這些資訊,從而編寫更加具有可移植性的代碼。嚴格地說,反射並非程式設計語言的特性,因為在任何一種語言都可以實現反射機制,但是如果程式設計語言本身支援反射,那麼反射的實現就會方便很多。我們知道在Java中一切都是對象,我們一般所使用的對象都直接或間接繼承自Object類。Object類中包含一個方法名叫getClass,利用這個方法就可以獲得一個執行個體的類型類。類型類指的是代表一個類型的類,因為一切皆是對象,類型也不例外,在Java使用類型類來表示一個類型。所有的類型類都是Class類的執行個體。例如,有如下一段代碼:
A a = new A();if(a.getClass()==A.class) System.out.println("equal");else System.out.println("unequal");結果就是列印出 “equal”。可以看到,對象a是A的一個執行個體,A某一個類,在if語句中使用a.getClass()返回的結果正是A的類型類,在Java中表示一個特定類型的類型類可以用“類型.class”的方式獲得,因為a.getClass()獲得是A的類型類,也就是A.class,因此上面的代碼執行的結果就是列印出 “equal”。特別注意的是,類型類是一一對應的,父類的類型類和子類的類型類是不同的,因此,假設A是B的子類,那麼如下的代碼將得到 “unequal”的輸出:
A a = new A();if(a.getClass()==B.class) System.out.println("equal");else System.out.println("unequal");
因此,如果你知道一個執行個體,那麼你可以通過執行個體的“getClass()”方法獲得該對象的類型類,如果你知道一個類型,那麼你可以使用“.class”的方法獲得該類型的類型類。
聯絡 一般情況下,getclass()方法和class()方法是等價的,都可以獲得一個類型名,例如下面的代碼:
在比較一個類是否和另一個類屬於同一個類執行個體的時候,我們通常可以採用instanceof和getClass兩種方法通過兩者是否相等來判斷,但是兩者在判斷上面是有差別的,下面從代碼中看看區別:
public class Test { public static void testInstanceof(Object x) { System.out.println("x instanceof Parent: "+(x instanceof Parent)); System.out.println("x instanceof Child: "+(x instanceof Child)); System.out.println("x getClass Parent: "+(x.getClass() == Parent.class)); System.out.println("x getClass Child: "+(x.getClass() == Child.class)); } public static void main(String[] args) { testInstanceof(new Parent()); System.out.println("---------------------------"); testInstanceof(new Child()); } } class Parent { } class Child extends Parent { } /* 輸出: x instanceof Parent: true x instanceof Child: false x getClass Parent: true x getClass Child: false --------------------------- x instanceof Parent: true x instanceof Child: true x getClass Parent: false x getClass Child: true */
從程式輸出可以看出,instanceof進行類型檢查規則是:你屬於該類嗎。或者你屬於該類的衍生類別嗎。而通過getClass獲得類型資訊採用==來進行檢查是否相等的操作是嚴格的判斷。不會存在繼承方面的考慮;
區別兩者最直接的區別就是,getClass()是一個類的執行個體所具備的方法,而class()方法是一個類的方法。
另外getClass()是在運行時才確定的,而class()方法是在編譯時間就確定了。
例如下面的程式:
class A{ public void func(){ }}class B extends A{}public class Test { public static void main(String[] args) { A a = new A(); B b = new B(); A ab = new B(); System.out.println(a.getClass()+" "+A.class); System.out.println(b.getClass()+" "+B.class); System.out.println(ab.getClass()); ab = a; System.out.println(ab.getClass()); }}
輸出結果為:
class A class A class B class B class B class A