利用Java泛型怎么獲取T.class?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
成都創(chuàng)新互聯(lián)公司自2013年創(chuàng)立以來,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元淮安區(qū)做網(wǎng)站,已為上家服務(wù),為淮安區(qū)各地企業(yè)和個人服務(wù),聯(lián)系電話:13518219792
泛型的四點作用:
第一是泛化,可以拿個T代表任意類型。 但GP是被C++嚴(yán)苛的靜態(tài)性逼出來的,落到Java、C#這樣的花語平原里----所有對象除幾個原始類型外都派生于Object,再加上Java的反射功能,Java的Collection庫沒有范型一樣過得好好的。
第二是泛型 + 反射,原本因為Java的泛型拿不到T.class而覺得泛型沒用,最近才剛剛學(xué)到通過反射的API來獲取T的Class,后述。
第三是收斂,就是增加了類型安全,減少了強制類型轉(zhuǎn)換的代碼。這點倒是Java Collection歷來的弱項。
第四是可以在編譯期搞很多東西,比如MetaProgramming。但除非能完全封閉于框架內(nèi)部,框架的使用者和擴展者都不用學(xué)習(xí)這些東西的用法,否則那就是自絕于人民的票房毒藥。C++的MetaProgramming好厲害吧,但對比一下Python拿Meta Programming生造一個Class出來的簡便語法,就明白什么才是真正的叫好又叫座。
所以,作為一個架構(gòu)設(shè)計師,應(yīng)該使用上述的第2,3項用法,在框架類里配合使用反射和泛型,使得框架的能力更強; 同時采用收斂特性,本著對人民負(fù)責(zé)的精神,用泛型使框架更加類型安全,更少強制類型轉(zhuǎn)換。
擦拭法避免了Java的流血分裂 :
大家經(jīng)常罵Java GP的擦拭法實現(xiàn),但我覺得多虧于它的中庸特性---如果你用就是范型,不用就是普通Object,避免了Java陣營又要經(jīng)歷一場to be or not to be的分裂。
最大的例子莫過Java 5的Collection 框架, 比如有些同學(xué)堅持認(rèn)為自己不會白癡到類型出錯,而且難以忍受每個定義的地方都要帶一個泛型定義List〈Book〉,不用強制類型轉(zhuǎn)換所省下的代碼還不夠N處定義花的(對了,java里面還沒有tyepdef.....),因此對范型十分不感冒,這時就要齊齊感謝這個搽拭法讓你依然可以對一個泛型框架保持非泛型的用法了...
<<干貨來了!!!!!!>>
通過反射獲得 T.class:
abstract public class BaseHibernateEntityDao<T> extends HibernateDaoSupport { private Class<T> entityClass; public BaseHibernateEntityDao() { entityClass =(Class<T>) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; } public T get(Serializable id) { T o = (T) getHibernateTemplate().get(entityClass, id); return o; } }
重點就是這句話:
Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
解釋:
1. public Type getGenericSuperclass()
用來返回表示當(dāng)前Class 所表示的實體(類、接口、基本類型或 void)的直接超類的Type。如果這個直接超類是參數(shù)化類型的,則返回的Type對象必須明確反映在源代碼中聲明時使用的類型。比如:
import java.lang.reflect.ParameterizedType; public class GT1 extends GT2<Integer>{ public static void main(String[] args) { System.out.println(((ParameterizedType)new GT1().getClass().getGenericSuperclass())); } }
則輸出結(jié)果即為:
GT2<java.lang.Integer>
如果此Class代表的是Object 類、接口、基本類型或 void,則返回 null。。如果此對象表示一個數(shù)組類,則返回表示 Object 類的 Class 對象。
2. public Type[] getGenericInterfaces()
與上面那個方法類似,只不過Java的類可以實現(xiàn)多個接口,所以返回的Type必須用數(shù)組來存儲。
以上兩個方法返回的都是Type對象或數(shù)組,在我們的這個話題中,Class都是代表的參數(shù)化類型,因此可以將Type對象Cast成ParameterizedType對象。而 ParameterizedType對象有一個方法, getActualTypeArguments()。
public Type[] getActualTypeArguments()
用來返回一個Type對象數(shù)組,這個數(shù)組代表著這個Type聲明中實際使用的類型。接著使用上面的例子:
import java.lang.reflect.ParameterizedType; public class GT1 extends GT2<Integer>{ public static void main(String[] args) { System.out.println(((ParameterizedType)new GT1().getClass().getGenericSuperclass()).getActualTypeArguments()[0]); } }
這次的顯示結(jié)果將是:class java.lang.Integer
因此,我們可以通過繼承+反射的方法,來的到T.class。
需要說明的是,江南白衣使用的方法是將關(guān)鍵語句
Class < T > entityClass = (Class < T > ) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[ 0 ];
放在了超類,也就是聲明泛型的那個類的構(gòu)造方法中。這樣一來,子類在繼承具有泛型的超類時,會自動調(diào)用超類的構(gòu)造方法。在此超類的構(gòu)造方法中,調(diào)用的getClass返回的是子類的Class類型(與通常的重寫機制有悖,呵呵,有待深究,但測試結(jié)果確是如此),則在子類中就無需再顯式地使用getGenericInterfaces()和getGenericSuperclass()等方法了。
接著,再使用(Class<T>)對 getActualTypeArguments()返回的元素做casting,即可得到所謂的T.class。
泛型之后,所有BaseHibernateEntityDao的子類只要定義了泛型,就無需再重載getEnttityClass(),get()函數(shù)和find()函數(shù),銷益挺明顯的,所以SpringSide的Dao基類毫不猶豫就泛型了。
不過擦拭法的大棒仍在,所以子類的泛型語法可不能亂寫,最正確的用法只有:
public class BookDao extends BaseHibernateEntityDao<Book>
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。
本文名稱:利用Java泛型怎么獲取T.class
當(dāng)前路徑:http://www.rwnh.cn/article42/gopchc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、靜態(tài)網(wǎng)站、網(wǎng)站設(shè)計、ChatGPT、定制網(wǎng)站、服務(wù)器托管
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)