女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

JAVA中注解是怎么做到的(下)

jf_78858299 ? 來(lái)源:JAVA旭陽(yáng) ? 作者:JAVA旭陽(yáng) ? 2023-05-11 10:57 ? 次閱讀

使用反射操作注解

大部分情況下,我們的項(xiàng)目或者開(kāi)源框架中都定義了大量的注解,而且都是@Retention(RetentionPolicy.RUNTIME)運(yùn)行時(shí)階段,我們可以通過(guò)反射獲取注解中的信息,所以整體遵循下面的一個(gè)范式。

  1. 自定義注解
  2. 掃描注解
  3. 通過(guò)反射獲取注解的信息,執(zhí)行相應(yīng)的邏輯。

下面我們重點(diǎn)使用下如何用反射來(lái)獲取注解的信息。

  1. 定義target是注解的注解
@Inherited
@Retention( value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.ANNOTATION_TYPE})
public @interface AnnoTest {

    String value() default "anno";

}
  1. 定義一個(gè)幾乎全量信息的注解
@AnnoTest("alvinAnno")
@Inherited
@Retention( value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE_USE,ElementType.PACKAGE,ElementType.FIELD,
        ElementType.TYPE_PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})
@Documented
public @interface FullAnnoTest {

    String value() default  "FullAnnoTest";

}
  1. 定義測(cè)試類和反射代碼
@FullAnnoTest("package")
package com.alvin.java.core.anno;

public class ParentObj {
}



@FullAnnoTest("testAnnoReflect")
public class TestAnnoReflect<@FullAnnoTest("parameter") T > extends @FullAnnoTest("parent")ParentObj {

    @FullAnnoTest("constructor")
    TestAnnoReflect() {
    }

    //注解字段域
    private @FullAnnoTest("name") String name;
    //注解泛型字段域
    private @FullAnnoTest("value") T value;
    //注解通配符
    private @FullAnnoTest("list") List<@FullAnnoTest("generic") ?> list;
    //注解方法
    @FullAnnoTest("method")                       //注解方法參數(shù)
    public String hello(@FullAnnoTest("methodParameter") String name)
            throws @FullAnnoTest("Exception") Exception { // 注解拋出異常
        //注解局部變量,現(xiàn)在運(yùn)行時(shí)暫時(shí)無(wú)法獲取(忽略)
        @FullAnnoTest("result") String result;
        result = "siting";
        System.out.println(name);
        return  result;
    }

    public static void main(String[] args) throws Exception {

        TestAnnoReflect
  1. 查看對(duì)應(yīng)的執(zhí)行結(jié)果
修飾TestAnnoReflect.class注解value: testAnnoReflect
修飾構(gòu)造器的注解value: constructor
修飾繼承父類的注解value: parent
修飾注解的注解AnnoTest-value: alvinAnno
修飾泛型參數(shù)T注解value: parameter
修飾普通字段域name注解value: name
修飾泛型字段T注解value: value
修飾泛型注解value: list
修飾通配符注解value: generic
修飾方法的注解value: method
修飾方法拋出錯(cuò)誤的注解value: Exception
修飾方法參數(shù)注解value: methodParameter
修飾package注解value: package
hello

注解的本質(zhì)和底層實(shí)現(xiàn)

大家有沒(méi)有想過(guò)注解的本質(zhì)是什么?

我們先通過(guò)反編譯查看注解生成的字節(jié)碼,可以通過(guò)javap -v FullAnnoTest.class查看如下:

圖片

可以看到,我們的注解是繼承自Annotation接口

public interface Annotation {
    boolean equals(Object obj);

    int hashCode();

    String toString();

    /**
     * Returns the annotation type of this annotation.
     * @return the annotation type of this annotation
     */
    Class? extends Annotation annotationType();
}

所以注解相當(dāng)于一個(gè)語(yǔ)法糖一樣,可以方便我們使用,本質(zhì)上它是繼承自Annotation的一個(gè)接口。

那大家有沒(méi)有想過(guò)它的實(shí)現(xiàn)類在哪里?比如下面的代碼,獲取到注解,按照上面的解釋,它是一個(gè)接口,那調(diào)用value()方法時(shí),它具體調(diào)用的哪個(gè)實(shí)現(xiàn)類呢?我們并沒(méi)有寫(xiě)實(shí)現(xiàn)類啊.....

答案當(dāng)然就是動(dòng)態(tài)代理生成的實(shí)現(xiàn)類。

AnnoTest annoTest = testTmp.annotationType().getAnnotation(AnnoTest.class);
System.out.println("修飾注解的注解AnnoTest-value: "+annoTest.value());

我們可以在啟動(dòng)參數(shù)添加如下命令可以查看生成的代理類:-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true

圖片

執(zhí)行后,生成代理類如下,

圖片

代理大致的代碼如下:

public final class $Proxy2 extends Proxy implements FullAnnoTest {
    private static Method m1;
    private static Method m2;
    private static Method m4;
    private static Method m0;
    private static Method m3;

    public $Proxy2(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

  

    public final Class annotationType() throws  {
        try {
            return (Class)super.h.invoke(this, m4, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String value() throws  {
        try {
            return (String)super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m4 = Class.forName("com.alvin.java.core.anno.FullAnnoTest").getMethod("annotationType");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            m3 = Class.forName("com.alvin.java.core.anno.FullAnnoTest").getMethod("value");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

我們看value()方法,這里調(diào)用了super.h對(duì)象,也就是InvocationHandler對(duì)象,而我們注解用的是AnnotationInvocationHandler這個(gè)子類,我們?cè)趇nvoke方法中打個(gè)斷點(diǎn),就明白了~~

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2984

    瀏覽量

    106786
  • JDK
    JDK
    +關(guān)注

    關(guān)注

    0

    文章

    82

    瀏覽量

    16811
  • spring框架
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

    2090
收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Java中注解的作用

    Annotation 注解(Annotation),也叫元數(shù)據(jù)。一種代碼級(jí)別的說(shuō)明。它是JDK1.5及以后版本引入的一個(gè)特性,與類、接口、枚舉是在同一個(gè)層次。它可以聲明在包、類、字段、方法、局部變量
    的頭像 發(fā)表于 09-30 10:12 ?1285次閱讀
    <b class='flag-5'>Java</b><b class='flag-5'>中注解</b>的作用

    如何通過(guò)注解來(lái)優(yōu)化我們的Java代碼

    Java注解可以說(shuō)是我們編碼過(guò)程中最常用的。本篇文章將給大家介紹Java注解的概念、作用以及如何使用注解來(lái)提升代碼的可讀性和靈活性,并介紹如
    的頭像 發(fā)表于 09-30 11:39 ?867次閱讀

    PCB刻制線圈怎么做到

    `如附圖這種PCB刻制線圈是怎么做的,畫(huà)得這么圓是怎么做到的?`
    發(fā)表于 06-13 11:07

    詳細(xì)介紹了Java泛型、注解、并發(fā)編程

    介紹了Java泛型、注解、并發(fā)編程、數(shù)據(jù)傳輸與序列化、高效IO、容器集合、反射與類加載以及JVM重點(diǎn)知識(shí)線程、內(nèi)存模型、JVM運(yùn)行時(shí)內(nèi)存、垃圾回收與算法、Java中四種引用類型、GC 分代收集算法
    發(fā)表于 08-20 06:09

    HarmonyOS注解的使用方法分享

    定義我們的注解自定義注解1、聲明注解功能:檢測(cè)類中是否有規(guī)范的get方法新建java libray的module,命名為annotation,創(chuàng)建
    發(fā)表于 03-28 14:04

    斬波型運(yùn)放減少噪聲 怎么做到的?

    翻譯: TI信號(hào)鏈工程師 Tom Wang (王中南) 斬波型運(yùn)放提供較低的失調(diào)電壓,同時(shí)也極大地減少了1 / f(閃爍)噪聲。它是怎么做到的?這篇短文就來(lái)討論這個(gè)主題。
    發(fā)表于 04-08 04:04 ?1.2w次閱讀
    斬波型運(yùn)放減少噪聲 <b class='flag-5'>怎么做到</b>的?

    分析java注解基本概念

    什么是注解(Annotation): Annotation(注解)就是Java提供了一種元程序中的元素關(guān)聯(lián)任何信息和著任何元數(shù)據(jù)(metadata)的途徑和方法。Annotion(注解
    發(fā)表于 09-27 14:53 ?0次下載

    怎么做到快速修補(bǔ)板式喂料機(jī)軸頭磨損

    怎么做到快速修補(bǔ)板式喂料機(jī)軸頭磨損
    發(fā)表于 01-23 11:10 ?2次下載

    Spring Boot常用注解與使用方式

    企業(yè)開(kāi)發(fā)項(xiàng)目SpringBoot已經(jīng)是必備框架了,其中注解是開(kāi)發(fā)中的小工具(誰(shuí)處可見(jiàn)哦),用好了開(kāi)發(fā)效率大大提升,當(dāng)然用錯(cuò)了也會(huì)引入缺陷。
    的頭像 發(fā)表于 07-08 10:57 ?1616次閱讀

    注解定義Bean及開(kāi)發(fā)

    注解本質(zhì)是一個(gè)繼承了Annotation 的特殊接口,其具體實(shí)現(xiàn)類是Java 運(yùn)行時(shí)生成的動(dòng)態(tài)代理類。
    發(fā)表于 08-02 10:26 ?533次閱讀

    JAVA中注解怎么做到的(上)

    。它可以聲明在包、類、字段、方法、局部變量、方法參數(shù)等的前面,用來(lái)對(duì)這些元素進(jìn)行說(shuō)明,注釋。那么你知道JDK什么是元注解嗎?注解有哪些分類嗎?以及注解Java中最本質(zhì)究竟是什么東西,
    的頭像 發(fā)表于 05-11 10:57 ?808次閱讀

    3分鐘純Java注解搭個(gè)管理系統(tǒng)

    Erupt一個(gè)通用后臺(tái)管理框架,據(jù)說(shuō)有 超低代碼量 、 零前端代碼 、零 CURD操作 、無(wú)需建表 ,純Java注解開(kāi)發(fā) 等特色,號(hào)稱三分鐘就可以搭建一個(gè)完整的后臺(tái)管理系統(tǒng)。
    的頭像 發(fā)表于 07-28 11:27 ?1436次閱讀
    3分鐘純<b class='flag-5'>Java</b><b class='flag-5'>注解</b>搭個(gè)管理系統(tǒng)

    怎么做到EMC設(shè)計(jì)與產(chǎn)品設(shè)計(jì)同步?(上)

    怎么做到EMC設(shè)計(jì)與產(chǎn)品設(shè)計(jì)同步?|深圳比創(chuàng)達(dá)EMC(上)
    的頭像 發(fā)表于 08-28 14:56 ?669次閱讀
    <b class='flag-5'>怎么做到</b>EMC設(shè)計(jì)與產(chǎn)品設(shè)計(jì)同步?(上)

    怎么做到EMC設(shè)計(jì)與產(chǎn)品設(shè)計(jì)同步?(中)

    怎么做到EMC設(shè)計(jì)與產(chǎn)品設(shè)計(jì)同步?(中)相信不少人是有疑問(wèn)的,今天深圳市比創(chuàng)達(dá)電子科技有限公司就跟大家解答一
    的頭像 發(fā)表于 08-29 10:34 ?608次閱讀

    怎么做到EMC設(shè)計(jì)與產(chǎn)品設(shè)計(jì)同步?(

    怎么做到EMC設(shè)計(jì)與產(chǎn)品設(shè)計(jì)同步?|深圳比創(chuàng)達(dá)EMC(
    的頭像 發(fā)表于 08-30 10:44 ?619次閱讀