APT - 調(diào)用Annotation方法獲取Class對(duì)象出現(xiàn)MirroredTypeException異常

??最近樓主在使用APT寫(xiě)一個(gè)DI框架,這個(gè)框架主要是用于樓主的畢設(shè)項(xiàng)目中晌缘。但是在開(kāi)發(fā)這個(gè)框架時(shí)巍扛,遇到一個(gè)關(guān)鍵的問(wèn)題鬓长,就是調(diào)用Annotation的方法來(lái)獲取一個(gè)Class對(duì)象時(shí),結(jié)果在編譯時(shí)直接報(bào)錯(cuò)了巍糯,拋的異常就是MirroredTypeException異常啸驯。本文的目的是解決這個(gè)問(wèn)題。
??本文參考資料:

  1. Getting Class values from Annotations in an AnnotationProcessor

1.提出問(wèn)題

??樓主自定義了一個(gè)Annotation,這個(gè)Annotation需要傳遞一個(gè)Class對(duì)象鳞贷。如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Container {
    Class<?> value();
}

??然后坯汤,我在這個(gè)注解來(lái)標(biāo)記一個(gè)類(lèi),比如說(shuō)MainActivity:

@Container(MainActivity.Context.class)
public class MainActivity extends AppCompatActivity {

    @Inject
    String string1;
    @Inject("string")
    String string2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public static class Context {
        @Provides
        String string1;

        @Provides("string")
        String string2;
    }
}

??最后搀愧,再通過(guò)APT來(lái)掃描注解惰聂,拿到Container注解的對(duì)象,進(jìn)而獲取它內(nèi)部的Class對(duì)象,也就是MainActivity.Context的Class對(duì)象咱筛。一切都是那么的美好搓幌,但是現(xiàn)實(shí)的殘酷給我們當(dāng)頭一棒。就在我們開(kāi)心的build工程時(shí)迅箩,一個(gè)大大的異常出現(xiàn)我們的眼前--MirroredTypeException溉愁。
??剛開(kāi)始出現(xiàn)這個(gè)異常時(shí),我是一臉懵逼的饲趋。當(dāng)時(shí)簡(jiǎn)單百度了一下拐揭,說(shuō)是該類(lèi)還未編譯撤蟆,不能獲取它的Class對(duì)象。說(shuō)句實(shí)話堂污,當(dāng)時(shí)非常的沮喪家肯,框架的大概結(jié)構(gòu)都已經(jīng)固定了,突然出現(xiàn)一個(gè)這個(gè)問(wèn)題盟猖,就意味著當(dāng)前這條路是不通的讨衣。
??不過(guò)好在天無(wú)絕人之路,我找到了解決方法式镐。

1. 解決問(wèn)題

??根據(jù) Getting Class values from Annotations in an AnnotationProcessor這篇文章反镇,可以找到兩種解決辦法。我們來(lái)看看娘汞,不過(guò)在看解決方法之前歹茶,我們還是先來(lái)看看之前,我們通過(guò)Annation怎么獲取Class對(duì)象你弦。

            Class<?> clazz = key.getAnnotation(Container.class).value();

??正常來(lái)說(shuō)辆亏,這一句是沒(méi)有毛病,可就是在編譯時(shí)會(huì)拋MirroredTypeException異常鳖目,這也是本文需要解決的問(wèn)題“邕叮現(xiàn)在我們來(lái)看一下解決方案,一共有兩種领迈。

(1). 通過(guò)AnnotationMirrors來(lái)獲取

??從參看文章彻磁,我們首先可以找到第一種方法,就是通過(guò)AnnotationMirrors來(lái)獲取狸捅。我們來(lái)看看代碼:

    private String getClassFromAnnotation(Element key) {
        List<? extends AnnotationMirror> annotationMirrors = key.getAnnotationMirrors();
        for (AnnotationMirror annotationMirror : annotationMirrors) {
            if (Container.class.getName().equals(annotationMirror.getAnnotationType().toString())) {
                Set<? extends ExecutableElement> keySet = annotationMirror.getElementValues().keySet();
                for (ExecutableElement executableElement : keySet) {
                    if (Objects.equals(executableElement.getSimpleName().toString(), "value")) {
                        return annotationMirror.getElementValues().get(executableElement).getValue().toString();
                    }
                }
            }
        }
        return null;
    }

??上面的代碼我們能夠成功獲取這個(gè)Class對(duì)象的name字段衷蜓,更別說(shuō)Class對(duì)象。其中annotationMirror.getElementValues().get(executableElement)返回的是一個(gè)Object對(duì)象尘喝,所以如果是Class<?>[]類(lèi)型的話磁浇,可以直接進(jìn)行強(qiáng)轉(zhuǎn)。這里之所強(qiáng)調(diào)這一點(diǎn)朽褪,是跟第二種解決方案區(qū)別開(kāi)來(lái)置吓。

(2). 通過(guò)MirroredTypeException異常來(lái)獲取

??當(dāng)我們通過(guò)如上的方法獲取Class對(duì)象時(shí),會(huì)拋出MirroredTypeException異常缔赠,我們可以根據(jù)MirroredTypeException攜帶的相關(guān)信息來(lái)獲取我們想要的Class對(duì)象衍锚。

    private String getClassFromAnnotationV2(Element key) {
        try {
            key.getAnnotation(Container.class).value();
        } catch (MirroredTypeException e) {
            TypeMirror typeMirror = e.getTypeMirror();
            return typeMirror.toString();
        }
        return null;
    }

??這種方法比較trick,但是不能否認(rèn)嗤堰,這也是一種解決方案戴质,而且比第一種方法更加的簡(jiǎn)單。這里需要的注意的是:

MirroredTypeException 不能獲取Class對(duì)象,只能獲取相應(yīng)的ClassName,其次它只能獲取Class對(duì)象的ClassName告匠,而不能獲取Class數(shù)組對(duì)象的ClassName戈抄,如果想要獲取Class數(shù)組對(duì)象的ClassName,可以通過(guò)MirroredTypesException來(lái)獲取后专。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末呛凶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子行贪,更是在濱河造成了極大的恐慌,老刑警劉巖模闲,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件建瘫,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡尸折,警方通過(guò)查閱死者的電腦和手機(jī)啰脚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)实夹,“玉大人橄浓,你說(shuō)我怎么就攤上這事×梁剑” “怎么了荸实?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)缴淋。 經(jīng)常有香客問(wèn)我准给,道長(zhǎng),這世上最難降的妖魔是什么重抖? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任露氮,我火速辦了婚禮,結(jié)果婚禮上钟沛,老公的妹妹穿的比我還像新娘畔规。我一直安慰自己,他們只是感情好恨统,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布叁扫。 她就那樣靜靜地躺著,像睡著了一般畜埋。 火紅的嫁衣襯著肌膚如雪陌兑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天由捎,我揣著相機(jī)與錄音兔综,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛软驰,可吹牛的內(nèi)容都是我干的涧窒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼锭亏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼纠吴!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起慧瘤,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤戴已,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后锅减,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體糖儡,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有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
  • 文/蒙蒙 一罚随、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧羽资,春花似錦淘菩、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至腹暖,卻和暖如春汇在,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脏答。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工糕殉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亩鬼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓阿蝶,卻偏偏與公主長(zhǎng)得像雳锋,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子羡洁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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

  • ∝童心原創(chuàng)文學(xué)玷过,心動(dòng)只是偶然∝ 一張結(jié)婚證 文/倪崢&童心 我每天都是踩點(diǎn)上班,今天當(dāng)我走到檔案室門(mén)口的時(shí)候筑煮,一個(gè)...
    花開(kāi)半夏又過(guò)半閱讀 404評(píng)論 0 0
  • 總是冒出很多想法辛蚊,昨天晚上翻看微博,現(xiàn)在覺(jué)得有些心疼你真仲。因?yàn)槲覀兘?jīng)歷很像袋马,或許我也很心疼我自己吧,只是自己沒(méi)有察覺(jué)...
    西西_隨筆閱讀 271評(píng)論 0 0
  • 不知道從什么時(shí)候養(yǎng)成的午休習(xí)慣袒餐,所以每天吃過(guò)午飯就會(huì)美美的睡上一覺(jué),哪怕是小瞇一會(huì)谤狡,也是一種享受灸眼。 因?yàn)樽蛲韽膲?mèng)中...
    鳳221閱讀 122評(píng)論 0 0