java的Class類是java反射機制的基礎,經過Class類咱們能夠得到關於一個類的相關信息,下面咱們來了解一下有關java中Class類的相關知識!java
java.lang.Class是一個比較特殊的類,它用於封裝被裝入到JVM中的類(包括類和接口)的信息。對象
當一個類或接口被裝入的JVM時便會產生一個與之關聯的java.lang.Class對象,能夠經過這個Class對象對被裝入類的詳細信息進行訪問。接口
簡單的說,獲取某一個類所對應的Class對象能夠經過以下三種途徑:字符串
1. Object的getClass方法
java.lang.Object中定義有getClass方法:get
public final Class getClass()it
全部Java對象都具有這個方法。該方法用於返回與調用該方法對象所屬類關聯的Class對象,例如:io
Date date1 = new Date();class
Date date2 = new Date();基礎
Class c1 = date1.getClass();date
Class c2 = date2.getClass();
System.out.println(c1.getName()); // java.util.Date
System.out.println(c1 == c2); // true
上面的代碼中,調用Date對象date1的getClass方法將返回用於封裝Date類信息的Class對象。這裏調用了Class類的getName方法:
public String getName()
這個方法的含義很直觀,即返回所封裝的類的名稱。
須要注意的是,代碼中的date1和date2的getClass方法返回了相同的Class對象(c1==c2的值爲true)。這是由於,對於相同的類,JVM只會載入一次,而與該類對應的Class對象也只會存在一個,不管該類實例化了多少對象。
另外,須要強調的是,當一個對象被其父類的引用或其實現的接口類型的引用所指向的時,getClass方法返回的是與對象實際所屬類關聯的Class對象。例如:
List list = new ArrayList();
System.out.println(list.getClass().getName()); // java.util.ArrayList
上面的代碼中,語句list.getClass()方法返回的是list所指向對象實際所屬類java.util.ArrayList對應的 Class對象而並未java.util.List所對應的Class對象。有些時候能夠經過這個方法瞭解一個對象的運行時類型,例如:
HashSet set = new HashSet();
Iterator it = set.iterator();
System.out.println(it.getClass().getName()); //java.util.HashMap$KeyIterator
從代碼能夠看出,HashSet的iterator方法返回的是實現了Iterator接口的HashMap內部類(KeyIterator)對象。
由於抽象類和接口不可能實例化對象,所以不能經過Object的getClass方法得到與抽象類和接口關聯的Class對象。
2. 使用.class的方式
使用類名加「.class」的方式即會返回與該類對應的Class對象。例如:
Class clazz = String.class;
System.out.println(clazz.getName()); // java.lang.String
這個方法能夠直接得到與指定類關聯的Class對象,而並不須要有該類的對象存在。
3. 使用Class.forName方法
Class有一個著名的static方法forName:
public static Class forName(String className) throws ClassNotFoundException
該方法能夠根據字符串參數所指定的類名獲取與該類關聯的Class對象。若是該類尚未被裝入,該方法會將該類裝入JVM。
該方法聲明拋出ClassNotFoundException異常。顧名思義,當該方法沒法獲取須要裝入的類時(例如,在當前類路徑中不存在這個類),就會拋出這個異常。
例如,若是當前類路徑中存在Foo類:
package org.whatisjava.reflect;
public class Foo {
public Foo() {
System.out.println("Foo()");
}
static {
System.out.println("Foo is initialized");
}
}
運行下面的代碼:
Class clazz = Class.forName("org.whatisjava.reflect.Foo");
控制檯會有以下輸出:
Foo is initialized
Class.forName("org.whatisjava.reflect.Foo")首先會將reflection.Foo類裝入JVM,並 返回與之關聯的Class對象。JVM裝入Foo類後對其進行初始化,調用了其static塊中的代碼。須要注意的是:forName方法的參數是類的完 整限定名(即包含包名)。
區別於前面兩種獲取Class對象的方法。使用Class.forName方法所要獲取的與之對應的Class對象的類能夠經過字符串的方式給定。該方法一般用於在程序運行時根據類名動態的載入該類並得到與之對應的Class對象。
經過上面的文章相信你對java的反射機制有了必定的認識,同時也對java中Class類的用法有了比較清晰的理解,在咱們實際工做的過程當中,咱們不斷的運用java知識來解決實際生湖中的問題的時候咱們就能對java反射機制有一個更深刻的理解!