1.官方API對這兩個方法的介紹?
getSuperclass :
返回表示此 Class 所表示的實體(類、接口、基本類型或 void)的超類的 Class。如果此 Class 表示 Object 類、一個接口、一個基本類型或 void,則返回 null。如果此對象表示一個數組類,則返回表示該 Object 類的 Class 對象。
getGenericSuperclass :
返回表示此 Class 所表示的實體(類、接口、基本類型或 void)的直接超類的Type。如果超類是參數化類型,則返回的 Type 對象必須準確反映源代碼中所使用的實際類型參數。如果以前未曾創建表示超類的參數化類型,則創建這個類型。有關參數化類型創建過程的語義,請參閱 ParameterizedType 聲明。如果此 Class 表示 Object 類、接口、基本類型或 void,則返回 null。如果此對象表示一個數組類,則返回表示 Object 類的 Class 對象。
2.二者異同點
兩個方法都是獲取超類的類型,看一個例子:
打印結果 :
?
這兩者都能獲取父類的類型,但是如果我們換成下面形式,我們就可以找到兩個方法差別。
?
上面的方法, 我們使用 ”getGenericSuperclass()” 方法獲取父類的類型, 然后重新讀一遍該方法的說明 “如果超類是參數化類型,則返回的 Type 對象必須準確反映源代碼中所使用的實際類型參數 ”。 也就是這種方式可以獲取超類的參數類型, 也就是泛型中的”Integer”類型。
但是如果上面方法我們使用 ”getSuperclass()“ 方法就會出現類型轉換錯誤 ”java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType”。
再舉一個例子
父類:
package com.itheima.mytest;public class Person<T1, T2> {}
子類:
package com.itheima.mytest;import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;public class Student extends Person<Integer, String> {@SuppressWarnings("rawtypes")public static void main(String[] args) {Student student = new Student();// getClass() 獲得該類的類類型(即類型變量)Class clazz = student.getClass();// getSuperclass() 獲得該類的父類System.out.println(clazz.getSuperclass());// getGenericSuperclass() 獲得該類帶有泛型的父類Type type = clazz.getGenericSuperclass();System.out.println(type);// Type是 Java 編程語言中所有類型的公共高級接口。它們包括原始類型、參數化類型、數組類型、類型變量和基本類型。// ParameterizedType 參數化類型,即泛型// 將Type轉化為參數化類型(即泛型)ParameterizedType p = (ParameterizedType) type;// getActualTypeArguments() 獲取參數化類型的數組,泛型可能有多個Type[] actualTypeArguments = p.getActualTypeArguments();// 將Type轉化為類型變量(即Class)Class c1 = (Class) actualTypeArguments[0];Class c2 = (Class) actualTypeArguments[1];System.out.println(c1);System.out.println(c2);}
}
?運行結果
class com.itheima.mytest.Person
com.itheima.mytest.Person<java.lang.Integer, java.lang.String>
class java.lang.Integer
class java.lang.String
3. 實際應用
記得以前使用hibernate時候, 我們會為所有Dao創建一個BaseDao, 將一般的增刪改查操作抽取到BaseDao中。
下面就是一個例子 :?
我們將增刪改查一般操作放在BaseDao中, 但是在”查”過程中, 遇到問題。當使用Hibernate拼寫HQL時候, 查一張表需要知道這張表對應的對象的名稱 . 比如”t_user”對應”User” . 那么在HQL中需要使用”User”。
在上面構造方法中,父類BaseDao中獲取子類操作類型對象 (UserDao操作User, DepartmentDao操作Department),利用泛型然后使用反射里的 ”getGenericSuperclass” 方法, 就可以獲取到對應的類型 ,進而獲取對應的className 。