為啥要學(xué)習(xí)Java Type

參考文章
http://loveshisong.cn/%E7%BC%96%E7%A8%8B%E6%8A%80%E6%9C%AF/2016-02-16-Type%E8%AF%A6%E8%A7%A3.html

http://blog.csdn.net/gdutxiaoxu/article/details/68926515

話說學(xué)過java一直不知道Type這個(gè)東東,基礎(chǔ)還是不扎實(shí)呀~
為什么要學(xué)習(xí)這個(gè)東東呢朵诫?話說某一天小弟看到這么段代碼

public abstract class BaseActivity<T extends BasePresenter, E extends BaseModel> extends AppCompatActivity {
    public T mPresenter;
    public E mModel;
        @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = TUtil.getT(this, 0);
        mModel=TUtil.getT(this,1);
        ...

可以看到基類中定義了2個(gè)泛型一也,上限分別是BasePresenter,BaseModel

public class TUtil {

    private static Type genericSuperclass;

    public static <T> T getT(Object o, int i) {
        try {
            return ((Class<T>) ((ParameterizedType) (o.getClass()
                    .getGenericSuperclass())).getActualTypeArguments()[i])
                    .newInstance();
        } catch (InstantiationException e) {
        } catch (IllegalAccessException e) {
        } catch (ClassCastException e) {
        }
        return null;
    }

基類中生成T 转唉、E 對(duì)象的話我們肯定是不能new泛型的,那么生成的方法我有二種
① 使用注解依賴生成
② Java提供了運(yùn)行時(shí)期拿到類或者接口type信息的方法,這就需要了解Type和Class相關(guān)知識(shí)了

首先我們來一步步分析
mPresenter = TUtil.getT(this, 0); 中的this就是BaseActivity子類 ,調(diào)用getClass()獲取到子類對(duì)象的Class對(duì)象劝堪,然后調(diào)getGenericSuperclass()方法拿到BaseActivity的Type

我們看看api解釋

public Type getGenericSuperclass()
返回表示此Class
所表示的實(shí)體(類贬墩、接口呀闻、基本類型或 void)的直接超類的Type
。 
如果超類是參數(shù)化類型秤涩,則返回的Type

對(duì)象必須準(zhǔn)確反映源代碼中所使用的實(shí)際類型參數(shù)帜乞。如果以前未曾創(chuàng)建表示超類的參數(shù)化類型,則創(chuàng)建這個(gè)類型筐眷。有關(guān)參數(shù)化類型創(chuàng)建過程的語義黎烈,請參閱 ParameterizedType

聲明。如果此Class
表示Object
類匀谣、接口照棋、基本類型或 void,則返回 
null武翎。如果此對(duì)象表示一個(gè)數(shù)組類烈炭,則返回表示Object類的Class對(duì)象。 

這里我們要明白Type是什么

public interface TypeType 是 Java 編程語言中所有類型的公共高級(jí)接口宝恶。它們包括原始類型梳庆、參數(shù)化類型、數(shù)組類型卑惜、類型變量和基本類型。 

簡單說Type就是所有類型的原始接口,Type接口有幾個(gè)子接口
所有已知子接口:
GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardType

ParameterizedType 表示參數(shù)化類型驻售,如 Collection<String>
類似這種參數(shù)泛型的對(duì)象得到的Type都是ParameterizedType

Type  getGenericSuperclass()
返回表示此 Class 所表示的實(shí)體(類露久、接口、基本類型或 void)的直接超類的 Type欺栗。

拿到這個(gè)對(duì)象的所有參數(shù)類型的一個(gè)數(shù)組毫痕,比如Map<String,Person> map 這個(gè) ParameterizedType 返回的是 String 類,Person 類的全限定類名的 Type Array。
并且這個(gè)方法返回的是當(dāng)前類對(duì)象的直接父類的Type
比如上面案例代碼中獲得的Type就是直接父類的Type迟几,但是具體參數(shù)類型是子類申明的消请!這點(diǎn)需要注意

com.jaydenxiao.common.base.BaseActivity<com.jaydenxiao.androidfire.ui.news.presenter.NewsDetailPresenter, com.jaydenxiao.androidfire.ui.news.model.NewsDetailModel>

而拿到Type后就可以調(diào)用
Type[] getActualTypeArguments() 獲取此類型實(shí)際類型參數(shù)的 Type 對(duì)象的數(shù)組。
然后index 0就是申明的第一個(gè)類型參數(shù)com.jaydenxiao.androidfire.ui.news.presenter.NewsDetailPresenter
index1就是申明的第二個(gè)參數(shù)
com.jaydenxiao.androidfire.ui.news.model.NewsDetailModel
Type拿到了就可以強(qiáng)轉(zhuǎn)成Class對(duì)象調(diào)然后生成指定泛型類型的對(duì)象了
getRawType() 返回的就是getGenericSuperclass()

TypeVariable<D extends GenericDeclaration>:
api解釋----->各種類型變量的公共高級(jí)接口
這個(gè)就是我們聲明的成員變量的類型,<D extends GenericDeclaration>
GenericDeclaration這個(gè)是什么呢类腮?
舉個(gè)例子如果我在類中這樣申明泛型

class Demo<T extends Serializable & Comparable,V> 
T t;
V v;

那么t的Type就是TypeVariable類型, 拿到TypeVariable對(duì)象后可以通過
getBounds()獲取到Type[]數(shù)組,由于這里我們指定t的類型為T并且這里通過&進(jìn)行上限符連接,所以getBounds拿到的都是一個(gè)數(shù)組,里面分別是Serializable,Comparable具體類型Class
同理v的TypeVariable的getBounds()拿到的就是V的具體類型的Class

D getGenericDeclaration()
這個(gè)方法獲取的是一個(gè)GenericDeclaration或者繼承GenericDeclaration的對(duì)象,拿到這個(gè)對(duì)象后調(diào)用getTypeParameters()方法可以拿到一個(gè)
TypeVariable<?>[]數(shù)組

QQ截圖20170620110646.png

而每個(gè)元素都可以通過getBounds()拿到Type[]數(shù)組然后得到每一個(gè)Class

GenericArrayType: 數(shù)組參數(shù)化類型
它就是由ParameterizedType或者TypeVariable<D>組成的數(shù)組
比如這種類型
T [] t 臊泰、 Collection<String> [] collections 這些都是GenericArrayType類型
一般我們在方法中申明這種參數(shù)類型時(shí),通過反射可以拿到方法中的參數(shù)類型

WildcardType 通配符類型
首先通配符 蚜枢? 這個(gè)概念可能很多童鞋會(huì)模糊缸逃,它跟前面申明的泛型T针饥、K啊什么的什么區(qū)別呢?
其實(shí)需频?就是一個(gè) 不確定的類型,如果我們簡單這樣申明一個(gè)Class類比如

class Simple <E>{
 }

我們這樣創(chuàng)建Simple simple=new Simple(); 代表什么都不申明那么編譯時(shí)E就會(huì)被抹除,而用到E的地方都會(huì)被替換成Object,如果我們這樣申明Simple<String>simple=new Simple(); 那么E就會(huì)申明為String類型丁眼,編譯時(shí)都會(huì)被替換為String類型, 那如果這樣申明Simple<?>simple=new Simple(); 跟前面我們什么都不申明效果是一樣的,那么?與(E昭殉、T)區(qū)別是我總結(jié)了幾點(diǎn):

  1. 苞七?不能直接申明在類上,比如上面的這樣申明就會(huì)編譯報(bào)錯(cuò), 原因在2.
class Simple <挪丢?>{
 }
  1. 類中申明的(E蹂风、T)是可以直接操作的,比如可以e=new E(),但是你沒法也不能? d=new ?();這樣這也是上面為什么沒法申明? 因?yàn)闆]意義
class Simple <E>{
     E e;
 }
  1. 那么你要疑問?有什么用,我們一般用作在方法中參數(shù)類的申明限定符,比如List中的
boolean addAll(Collection<? extends E> var1);

addAll參數(shù)是是一個(gè)Collection<? extends E> 吃靠,這樣申明我們就只能添加申明E子類類型的Collection硫眨,List <Object> object 這種addAll List <String> string沒事,但是反過來就會(huì)編譯錯(cuò)誤,

我們?nèi)绻@么申明一個(gè)變量 List <? extends View> list;
那么getGenericType()拿到的是ParameterizedType類型Type因?yàn)樗€是變量類型,然后調(diào)用getActualTypeArguments()就可以拿到<>里面的類型數(shù)組,因?yàn)榭赡苡?amp;符號(hào)連接形成多個(gè)類型,
那么類型數(shù)組里就是WildcardType 類型,而這個(gè)類型有二個(gè)方法
getLowerBounds() :顧名思義這個(gè)是獲取下邊界類型,List <? super View> list這樣獲取到的下邊界就是View
getUpperBounds() : 獲取上邊界類型巢块,比如上面申明獲取到的上邊界就是View

List <?> list;如果我們單獨(dú)就這么申明的話那么只能通過getUpperBounds() 獲取到Object

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末礁阁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子族奢,更是在濱河造成了極大的恐慌姥闭,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件越走,死亡現(xiàn)場離奇詭異棚品,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)廊敌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門铜跑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人骡澈,你說我怎么就攤上這事锅纺。” “怎么了肋殴?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵囤锉,是天一觀的道長。 經(jīng)常有香客問我护锤,道長官地,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任烙懦,我火速辦了婚禮驱入,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己沧侥,他們只是感情好可霎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宴杀,像睡著了一般癣朗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旺罢,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天旷余,我揣著相機(jī)與錄音,去河邊找鬼扁达。 笑死正卧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的跪解。 我是一名探鬼主播炉旷,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼叉讥!你這毒婦竟也來了窘行?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤图仓,失蹤者是張志新(化名)和其女友劉穎罐盔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體救崔,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惶看,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了六孵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纬黎。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖劫窒,靈堂內(nèi)的尸體忽然破棺而出莹桅,到底是詐尸還是另有隱情,我是刑警寧澤烛亦,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站懂拾,受9級(jí)特大地震影響煤禽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜岖赋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一檬果、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦选脊、人聲如沸杭抠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽偏灿。三九已至,卻和暖如春钝的,著一層夾襖步出監(jiān)牢的瞬間翁垂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國打工硝桩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沿猜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓碗脊,卻偏偏與公主長得像啼肩,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子衙伶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法祈坠,類相關(guān)的語法,內(nèi)部類的語法痕支,繼承相關(guān)的語法颁虐,異常的語法,線程的語...
    子非魚_t_閱讀 31,641評(píng)論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理卧须,服務(wù)發(fā)現(xiàn)另绩,斷路器,智...
    卡卡羅2017閱讀 134,665評(píng)論 18 139
  • 對(duì)象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法花嘶,而不是構(gòu)造函數(shù)創(chuàng)建對(duì)象:僅僅是創(chuàng)建對(duì)象的方法笋籽,并非Fa...
    孫小磊閱讀 1,986評(píng)論 0 3
  • 《Effective Java》筆記(上) 對(duì)象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法,而不是構(gòu)造...
    OCNYang閱讀 2,594評(píng)論 2 17
  • 《同讀一本書》2016-11-09-119 正文: 承 諾依品質(zhì)性的人際觀點(diǎn)來看椭员,承諾是成功溝通的特征之一车海。換句話...
    臺(tái)東萬達(dá)DDM一店張春燕閱讀 176評(píng)論 0 0