成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

java-Annotation注解

skinner / 3496人閱讀

摘要:指定該策略的注解只能修飾成員變量。也可以在定義注解的成員變量時(shí)為其指定初始值,指定默認(rèn)值。根據(jù)注解是否可以包含成員變量,可以把注解分為標(biāo)記注解沒(méi)有定義成員變量的注解類(lèi)型被稱(chēng)為標(biāo)記。

@Override

是告訴編譯器檢查這個(gè)方法,保證父類(lèi)要包含一個(gè)被該方法重寫(xiě)的方法,否則編譯出錯(cuò)。

只能修飾方法,不能修飾其他程序元素 。

Java 9 增強(qiáng)的@Deprecated

表示某個(gè)程序元素已經(jīng)過(guò)時(shí)。

Java 9 為@Deprecated注解增加了如下兩個(gè)屬性

ForRemoval:該boolean類(lèi)型的屬性指定該API在將來(lái)是否會(huì)被刪除。

Since:該String類(lèi)型的屬性指定該API從哪個(gè)版本被標(biāo)記為過(guò)時(shí)。

public class DeprecatedS {
    //已過(guò)時(shí),since是從9版本開(kāi)始,forRemoval指定該API將來(lái)會(huì)被刪除
    @Deprecated(forRemoval=true,since="9")
    public void info() {
    }
    public static void main(String[] args) {
        DeprecatedS s = new DeprecatedS();
        s.info();
    }
}
抑制編譯器警告:@SuppressWarnings

指示被該注解修飾的程序元素,以及該程序元素中的所有子元素,取消顯示指定的編譯器警告。@SuppressWarnings會(huì)一直作用于該程序元素的所有子元素。

//關(guān)閉整個(gè)類(lèi)里的編譯器警告
@SuppressWarnings(value="unchecked")
public class SuppressWarningsS {
    public static void main(String[] args) {
        List list = new ArrayList();
    }
}
堆污染警告 與 java 9 增強(qiáng)的@SafeVarargs

當(dāng)把一個(gè)不帶泛型的對(duì)象賦給一個(gè)帶泛型的變量時(shí),往往就會(huì)發(fā)生堆污染

public class SafeVarargsS {
    public static void main(String[] args) {
    }
    //Type safety: Potential heap pollution via varargs parameter list
    //類(lèi)型安全:通過(guò)varargs參數(shù)列表的潛在堆污染。
    public static void ai(List ...list) {
        List[] list2 = list;
        List myList = new ArrayList<>();
        myList.add(new Random().nextInt(100));
        list2[0] = myList;
        String string = list[0].get(0);
    }
}

上面程序中的粗體字代碼已經(jīng)發(fā)生了堆污染,由于該方法有個(gè)形參是List...類(lèi)型,個(gè)數(shù)可變的形參相當(dāng)于數(shù)組,但java又不會(huì)支持泛型數(shù)組,因此程序只能把List...當(dāng)成List[]處理,這里發(fā)生了堆污染。

使用@SafeVarargs

@SafeVarargs
public static void ai(List ...list) {}
Java 8的函數(shù)式接口 @FuncationInterface

如果接口中只有一個(gè)抽象方法,可以包含多個(gè)默認(rèn)方法或多個(gè)static方法,該接口就是函數(shù)式接口。

@FuncationInterface就是用來(lái)指定某個(gè)接口必須是函數(shù)式接口。

@FunctionalInterface
public interface Function {}

FuncationInterface只能修飾接口,不能修飾其他元素

JDK的元注解

在java.lang.annotation包下提供了6個(gè)Meta注解(元注解),@Repeatable專(zhuān)門(mén)用于定義java 8新增的重復(fù)注解。

使用@Retention :保留,扣留 Policy:政策,方針

@Retention只能用于修飾注解定義,用于指定被修飾的注解可以保留多長(zhǎng)時(shí)間,他包含一個(gè)RetentionPolicy類(lèi)型的value成員變量,所以使用時(shí)必須為該value成員變量指定值。

Value成員變量的值只能是如下三個(gè)

RetentionPolicy.CLASS : 編譯器將把注解記錄在class中,當(dāng)運(yùn)行java程序時(shí),JVM不可獲得注解信息,這是默認(rèn)值。

RetentionPolicy.REUNTIME:編譯器將把注解記錄在class文件中,當(dāng)運(yùn)行java程序時(shí),JVM也可獲取注解信息,程序可以通過(guò)反射獲得該注解信息。

RetentionPolicy.SOURCE:注解只保留在源代碼中,編譯器直接丟棄這種注解。

使用

@Retention(value = RetentionPolicy.RUNTIME)
public @interface My1 {}
@Retention(RetentionPolicy.RUNTIME)
public @interface My1 {}

使用@Target

只能修飾注解定義,它用于指定被修飾的注解能用于修飾那些程序單元。

@Target元注解也包含一個(gè)value成員變量

成員變量如下

ElementType.ANNOTATION_TYPE:指定該策略的注解只能修飾注解。

ElementType.CONSTRUCTOR:指定該策略的注解只能修飾構(gòu)造器。

ElementType.FIELD:指定該策略的注解只能修飾成員變量。

ElementType.LOCAL_VARIABLE:指定該策略的注解只能修飾局部變量。

ElementType.METHOD:指定該策略的注解只能修飾方法。

ElementType.PACKAGE:指定該策略的注解只能修飾包定義。

ElementType.PARAMETER:指定該策略的注解只能修飾參數(shù)。

ElementType.TYPE:指定該策略的注解只能修飾類(lèi),接口,注解類(lèi)型,枚舉定義。

使用

@Target(value = ElementType.ANNOTATION_TYPE)
public @interface My1 {}

使用@Document

@Document用于指定被該元注解修飾的注解類(lèi)將被javadoc工具提取城文檔,如果定義注解類(lèi)時(shí)使用了@Document,則所有使用該注解修飾的程序元素的API文檔中將會(huì)包含該注解說(shuō)明。

使用@Inherited : 可繼承的

指定被他修飾的注解將具有繼承性。

@Inherited
public @interface My1 {}

上面程序中代碼表明@My1具有繼承性,如果某個(gè)類(lèi)使用@My1修飾,則該類(lèi)的子類(lèi)將自動(dòng)使用@My1修飾。

檢查其子類(lèi)是否默認(rèn)使用@My1修飾。

@My1
class A{}
public class My1_Test extends A {
    public static void main(String[] args) {
        System.out.println(My1_Test.class.isAnnotationPresent(My1.class));//true
    }
}
自定義注解

定義新的注解使用@Interface關(guān)鍵字定義一個(gè)新的注解類(lèi)型與定義一個(gè)接口非常像,如下

public @interface My1 {}

定義了該注解之后,就可以在程序的任何地方使用該注解。

默認(rèn)情況下,注解可用于修飾任何程序元素,包括類(lèi),接口,方法等。

注解還可以帶成員變量,成員變量在注解定義中以無(wú)形參的方法形式來(lái)聲明,其方法名和返回值定義了該成員變量的名字和類(lèi)型。

public @interface My1 {
    String name();
    int id();
}

一旦在注解里定義了成員變量后,使用該注解時(shí)就應(yīng)該為他的成員變量指定值。

@My1(id=1,name="rrr")
class A{}
(6)    也可以在定義注解的成員變量時(shí)為其指定初始值,指定默認(rèn)值default。
public @interface My1 {
    String name() default "ccc";
    int id() default 123;
}

成員變量指定了值,則默認(rèn)值就不會(huì)起作用。

根據(jù)注解是否可以包含成員變量,可以把注解分為

標(biāo)記注解:沒(méi)有定義成員變量的注解類(lèi)型被稱(chēng)為標(biāo)記。這種注解僅利用自身的存在與否來(lái)提供信息,如@Test、

元數(shù)據(jù)注解:包括成員變量的注解,因?yàn)樗麄兛梢越邮芨嗟脑獢?shù)據(jù),所以也被稱(chēng)為元數(shù)據(jù)注解。

提取注解信息

使用注解修飾了類(lèi),方法,成員變量等之后,這些注解不會(huì)自己生效,必須由開(kāi)發(fā)者提供相應(yīng)的工具來(lái)提取并處理注解信息。

AnnotatedElement接口,該接口代表程序中可以接受注解的程序元素,該接口主要有如下個(gè)實(shí)現(xiàn)類(lèi):

Class:類(lèi)定義

Constructor:構(gòu)造器定義

Field:類(lèi)的成員變量定義

Method:類(lèi)的方法定義

Package:類(lèi)的包定義

只有當(dāng)定義注解時(shí)使用了@Retention(RetentionPolicy.RUNTIME)修飾,該注解才會(huì)在運(yùn)行時(shí)可見(jiàn),JVM才會(huì)在裝載class文件時(shí)讀取保存在class文件中的注解信息。

獲取My2類(lèi)的方法上的Annotation

public class My2 {
    @My1(id =123,name ="dsds")
    public void info() {
    }
}
public class GetMy2Annotation{
    public static void main(String[] args) throws Exception{
        Class forName = Class.forName("annotations.My2");//加載類(lèi)
        Method method = forName.getMethod("info");//得到方法
        Annotation[] annotations = method.getAnnotations();//得到方法上所有注解
        //@annotations.My1(name="dsds", id=123)
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}

訪(fǎng)問(wèn)注解中的元數(shù)據(jù)

public class GetMy2Annotation{
    public static void main(String[] args) throws Exception{
        Class forName = Class.forName("annotations.My2");//加載類(lèi)
        Method method = forName.getMethod("info");//得到方法
        Annotation[] annotations = method.getAnnotations();//得到方法上所有注解
        /*
         * 123
         * dsds
         * */
        for (Annotation annotation : annotations) {
            if (annotation instanceof My1) {
                System.out.println(((My1)annotation).id());
                System.out.println(((My1)annotation).name());
            }
        }
    }
}

利用注解模擬@Test的JUnit效果

public class RunTest {
    public static void main(String[] args) throws Exception {
        Class forName = Class.forName("annotations.RunTest_JUnit");//加載類(lèi)
        Method[] methods = forName.getDeclaredMethods();//獲得本類(lèi)所有方法
        int success = 0;//成功方法
        int fail = 0;//失敗方法
        for (Method method : methods) {
            System.out.println(method);
            System.out.println(method.isAnnotationPresent(Testable.class));
            if (method.isAnnotationPresent(Testable.class)) {
                try {
                    //抑制private訪(fǎng)問(wèn)修飾符
                    method.setAccessible(true);
                    method.invoke( null);
                    success++;
                } catch (Exception e) {
                    fail++;
                }
            }
        }
        System.out.println("成功方法有:" + success +"個(gè)   失敗的有:"+fail+"個(gè)");
    }
}
class RunTest_JUnit{
    @Testable
    private static void t() {
        System.out.println("=========================t");
    }
    private static void t1() {
    }
    @Testable
    private static void t2() {
        System.out.println("=========================t2");
    }
    @Testable
    private static void r2() {
        System.out.println("=========================r2");
        throw new RuntimeException("出錯(cuò)誤啦");
    }
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Testable{
}

Output:
private static void annotations.RunTest_JUnit.t1()
false
private static void annotations.RunTest_JUnit.t()
true
=========================t
private static void annotations.RunTest_JUnit.r2()
true
=========================r2
private static void annotations.RunTest_JUnit.t2()
true
=========================t2
成功方法有:2個(gè)   失敗的有:1個(gè)

上面的@Testable用于標(biāo)記那些方法是可測(cè)試的,該注解可以作為JUnit測(cè)試框架的補(bǔ)充,在JUnit框架中他要求測(cè)試用例的測(cè)試方法必須以test開(kāi)頭。

Java 8 新增的重復(fù)注解
@Retention(RetentionPolicy.RUNTIME)
@Target(value=ElementType.TYPE)
@Repeatable(value=FkTags.class)//只能可以包容它的容器類(lèi)
public @interface FkTag {
    String name() default "王自強(qiáng)";
    int id();
}

@Retention(RetentionPolicy.RUNTIME)
@Target(value=ElementType.TYPE)
public @interface FkTags {
    FkTag[] value();
}

//@FkTags({@FkTag(id=1,name="dsd"),@FkTag(id=213)})
@FkTag(id=123)
@FkTag(id=1233)
public class Test_FkTage {
    public static void main(String[] args) {
        Class cl = Test_FkTage.class;//獲取類(lèi)
        //這個(gè)方法可以獲得多個(gè)重復(fù)注解,而getDeclaredAnnotation只能獲取一個(gè)
        FkTag[] annotationsByType = cl.getAnnotationsByType(FkTag.class);
        for (FkTag fkTag : annotationsByType) {
            System.out.println(fkTag.id()+"      "+ fkTag.name());
        }
        FkTags annotation = cl.getAnnotation(FkTags.class);
        System.out.println(annotation);
    }
}
Output
123      王自強(qiáng)
1233      王自強(qiáng)
@fkAnnotation.FkTags(value={@fkAnnotation.FkTag(name="王自強(qiáng)", id=123), @fkAnnotation.FkTag(name="王自強(qiáng)", id=1233)})

如上的重復(fù)注解只是一種簡(jiǎn)便的寫(xiě)法,運(yùn)用@Repeatable注解來(lái)制定他的容器注解類(lèi)即可。

容器注解類(lèi)注解的保留期必須比他所包含的注解的保留期更長(zhǎng),否則編譯器報(bào)錯(cuò)。

Java 8新增的類(lèi)型注解
編寫(xiě)自定義注解時(shí)未寫(xiě)@Inherited的運(yùn)行結(jié)果 編寫(xiě)自定義注解時(shí)寫(xiě)了@Inherited的運(yùn)行結(jié)果
子類(lèi)的類(lèi)上能否繼承到父類(lèi)的類(lèi)上的注解?
子類(lèi)方法,實(shí)現(xiàn)了父類(lèi)上的抽象方法,這個(gè)方法能否繼承到注解?
子類(lèi)方法,實(shí)現(xiàn)了父類(lèi)上的方法,這個(gè)方法能否繼承到注解?
子類(lèi)方法,覆蓋了父類(lèi)上的方法,這個(gè)方法能否繼承到注解?

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69333.html

相關(guān)文章

  • Java? 教程(注解

    注解 注解(一種元數(shù)據(jù)形式)提供有關(guān)不屬于程序本身的程序的數(shù)據(jù),注解對(duì)它們注解的代碼的操作沒(méi)有直接影響。 注解有許多用途,其中包括: 編譯器的信息 — 編譯器可以使用注解來(lái)檢測(cè)錯(cuò)誤或抑制警告。 編譯時(shí)和部署時(shí)處理 — 軟件工具可以處理注解信息以生成代碼、XML文件等。 運(yùn)行時(shí)處理 — 可以在運(yùn)行時(shí)檢查某些注解。 本課程介紹了可以使用注解的位置,以及如何應(yīng)用注解,Java平臺(tái)標(biāo)準(zhǔn)版(Java S...

    econi 評(píng)論0 收藏0
  • Java 注解實(shí)戰(zhàn)

    摘要:注解是的一個(gè)新特性。很重要,生產(chǎn)中我們開(kāi)發(fā)常用此值表示注解是否可被子元素繼承。類(lèi)注解方法注解通過(guò)反射獲取方法對(duì)象此部分內(nèi)容可參考通過(guò)反射獲取注解信息注解處理器實(shí)戰(zhàn)接下來(lái)我通過(guò)在公司中的一個(gè)實(shí)戰(zhàn)改編來(lái)演示一下注解處理器的真實(shí)使用場(chǎng)景。 前言:Java 注解,對(duì)于很多人都不陌生了,但是在公司的實(shí)際開(kāi)發(fā)中,可能讓我們自己去定義注解并應(yīng)用到生產(chǎn)環(huán)境中的機(jī)會(huì)比較少,所以會(huì)導(dǎo)致一部分人對(duì)注解的理解...

    Jochen 評(píng)論0 收藏0
  • Java注解-元數(shù)據(jù)、注解分類(lèi)、內(nèi)置注解和自定義注解

    摘要:注解有以下幾個(gè)知識(shí)點(diǎn)元數(shù)據(jù)注解的分類(lèi)內(nèi)置注解自定義注解注解處理器本文先介紹前面?zhèn)€知識(shí)點(diǎn)元數(shù)據(jù)注解的分類(lèi)內(nèi)置注解自定義注解。注解相當(dāng)于是一種嵌入在程序中的元數(shù)據(jù),可以使用注解解析工具或編譯器對(duì)其進(jìn)行解析,也可以指定注解在編譯期或運(yùn)行期有效。 大家好,我是樂(lè)字節(jié)的小樂(lè),上次說(shuō)過(guò)了Java多態(tài)的6大特性|樂(lè)字節(jié),接下來(lái)我們來(lái)看看Java編程里的注解。showImg(https://segme...

    Yujiaao 評(píng)論0 收藏0
  • 注解(待完善)

    摘要:中提供了前四個(gè)元注解。在中新添加了最后一個(gè)注解。指定了注解可以用于的范圍。可以默認(rèn)設(shè)置為空字符串如果沒(méi)有默認(rèn)值的話(huà),在使用的時(shí)候則需要對(duì)它進(jìn)行賦值。反射程序運(yùn)行時(shí)獲取注解的值,設(shè)置為??梢允褂每兆址? 分類(lèi) 元注解(meta-annotation) java元注解就是用來(lái)注解其他注解??梢岳斫鉃樵⒔馐瞧渌x的注解的基礎(chǔ)。元注解有 @Retention、@Documented、@Ta...

    Channe 評(píng)論0 收藏0
  • Java之注解的定義及使用

    摘要:注解添加了注解的注解,所注解的類(lèi)的子類(lèi)也將擁有這個(gè)注解注解父類(lèi)子類(lèi)會(huì)把加在上的繼承下來(lái)在接口上添加注解,然后類(lèi)實(shí)現(xiàn)了接口,類(lèi)不會(huì)擁有接口上的注解。如果父類(lèi)刪除了該方法,則子類(lèi)會(huì)報(bào)錯(cuò)。注解表示被注解的元素已被棄用。 Java的注解在實(shí)際項(xiàng)目中使用得非常的多,特別是在使用了Spring之后。本文會(huì)介紹Java注解的語(yǔ)法,以及在Spring中使用注解的例子。 注解的語(yǔ)法 注解的例子 以Ju...

    songze 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<