1 認識 Class 類
在正常情況下,需要先有一個類的完整路徑,引入之後可以按照固定的格式産生執行個體化對象,但是在 Java 中也允許一個執行個體化對象找到一個類的完整資訊,那麼這就是 Class 類的功能。
執行個體 1 代碼:
package self.learn.reflect;
class X{ // 聲明 Class 類
}
public class GetClassDemo01 {
public static void main(String[] args) {
X x = new X(); // 執行個體化 X 類對象
System.out.println(x.getClass().getName()); // 得到對象所在類
}
}
運作結果截圖:
從上面代碼的運作結果可以發現,通過一個對象得到了對象所在的完整的“包.類”名稱,getClass()方法是 Object()類中繼承而來的,此方法定義如下:
以上的方法傳回值的類型是一個 “Class” 類,實際上此類是 Java 反射的源頭。所謂反射從程式的運作結果來看也很好了解,即可以通過對象反射求出類名,如圖:
- 正常方式:
- 反射方式:
所有類的對象實際上都是 Class 類的執行個體
在 Java 中 Object 類是一切類的父類,那麼所有類的對象實際上也就是 java.lang.Class 類的執行個體,是以所有的對象都可以轉變為 java.lang.Class 類型表示。
- Class 本身表示一個類本身,通過 Class 可以完整地得到一個類中的完整結構,包括此類中的方法定義、屬性定義等。如下表:
序号 | 方法 | 類型 | 描述 |
---|---|---|---|
1 | | 普通 | 傳入完整的“包.類” 名稱,執行個體化 Class 對象 |
2 | | 普通 | 得到一個類中的全部構造方法 |
3 | | 普通 | 得到一個類的父類中的全部屬性 |
4 | | 普通 | 取得本類的全部屬性 |
5 | | 普通 | 取得一個類中的全部方法 |
6 | | 普通 | 傳回一個 Method 對象,并設定一個方法中的所有參數類型 |
7 | | 普通 | 得到一個類中所實作的全部接口 |
8 | | 普通 | 得到一個類中完整的 “包.類” 名稱 |
9 | | 普通 | 得到一個類的包 |
10 | | 普通 | 得到一個類的父類 |
11 | | 普通 | 根據 Class 定義的類執行個體化對象 |
12 | | 普通 | 傳回表示數組類型的 class |
13 | | 普通 | 判斷此 Class 是否是一個數組 |
在 Class 類本身沒有定義任何的構造方法,是以如果要使用則首先必須通過 forName()的靜态方法執行個體化對象。除此之外 ,也可以使用“類.class” 或 “對象.getClass()”方法執行個體化。
執行個體 2 代碼:執行個體化 Class 類對象
package self.learn.reflect;
class X{ // 聲明 Class 類
}
public class GetClassDemo01 {
public static void main(String[] args) {
Class<?> c1 = null; // 指定泛型
Class<?> c2 = null; // 指定泛型
Class<?> c3 = null; // 指定泛型
try {
c1 = Class.forName("self.learn.reflect.X"); // 最常用的形式
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
c2 = new X().getClass(); // 通過 Object 類中的方法執行個體化
c3 = X.class; // 通過類.class 執行個體化
System.out.println("類名稱:"+c1.getName()); // 得到對象所在類
System.out.println("類名稱:"+c2.getName()); // 得到對象所在類
System.out.println("類名稱:"+c3.getName()); // 得到對象所在類
}
}
運作結果截圖:
從程式的運作結果可以發現 3 種執行個體化 Class 對象的方式是一樣的,但是使用 forName()的靜态方法執行個體化 Class 對象是一種比較常用的方式,讀者應重點掌握。
使用 forName()方法更加具備靈活性
從以上程式的 3 種使用方法可以發現,除了 forName()方法外,其他兩種:類.class” 或 “對象.getClass()”都需要導入一個明确的類,這樣如果一個類的操作不明确時,使用起來可能會受到一些限制。但是 forName()傳入時隻需要以字元串的方式傳入即可,這樣就讓程式具備了更大的靈活性,是以這種方式是最為常見的一種方式。