註解詳解

一:註解的做用

註解是jdk5引入的新特性,註解至關於增長了一個配置,當咱們使用註解時,咱們能夠經過反射獲取註解從而獲取相關的配置,方便咱們在代碼層面作一些操做。java

二:註解的相關概念以及使用

註解的分類:   

  • 供javadoc生成文檔用的註解。@param @return 等。
  • 自定義註解,至關於配置文件的做用,使用靈活,配置簡單。
  • 在編譯時進行格式檢查。@override檢查是否重寫了父類方法。@SuppressWarnings抑制編譯器產生的警告信息。@Deprecated標記過期的方法等不推薦再使用。

  包 java.lang.annotation 中包含全部定義自定義註解所需用到的元註解和接口。全部註解默認繼承了java.lang.annotation.Annotation接口。ide

註解中概念:

自定義註解時使用了四個元註解,就是用於註解的註解。四個元註解分別是:@Target,@Retention,@Documented,@Inherited。函數

@Target定義註解做用的地方。能夠是類、方法、屬性等。經常使用的值由一個枚舉類定義:ElementType。工具

ElementType.FIELD,//做用在屬性上
ElementType.METHOD,//做用在方法上
ElementType.CONSTRUCTOR,//做用在構造函數上
ElementType.LOCAL_VARIABLE,//做用在本地變量上
ElementType.PACKAGE,//做用在包上
ElementType.PARAMETER,//做用在方法參數上
ElementType.TYPE//做用在類,接口,枚舉類等

 

@Retention定義了註解的生命週期,即註解在什麼範圍內有效。spa

  • SOURCE:在源文件中有效
  • CLASS:在class文件中有效
  • RUNTIME:在運行時有效(即運行時保留,咱們自定義的註解通常是要在運行時使用的)

@Documented 表示此註解做用的內容會被javadoc工具提取到文檔中。code

@Inherited表示該註解會被繼承。使用該元註解的自定義註解通常做用範圍是ElementType.TYPE,若是是做用在ElementType.METHOD的註解,在子類重寫了使用註解的方法的時候,此時子類重載方法是沒有繼承該註解的,不重寫方法則子類能夠獲取繼承的註解。blog

 

自定義註解的方式:

使用@interface來定義一個自定義註解,使用方法定義自定義註解中的屬性,方法的返回值定義屬性值的類型。

註解使用案例一:

註解定義:繼承

      

@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DatasourceAnnotation {
    String datasourceName();
    int sequence();
}

 

註解使用:接口

public class UserService {
    @DatasourceAnnotation(datasourceName = "master", sequence = 1)
    public String datasourceName;

    @DatasourceAnnotation(datasourceName = "salve", sequence = 2)
    public String selectUserNameById(Integer id) {
        return "test";
    }
}

 

public class AnnotationTest {
    private void handleFieldAnnotation() throws NoSuchFieldException {
        Field datasourceName = UserService.class.getField("datasourceName");//獲取屬性
        if (datasourceName.isAnnotationPresent(DatasourceAnnotation.class)) {//判斷屬性上有無此註解
            DatasourceAnnotation annotation = datasourceName.getAnnotation(DatasourceAnnotation.class);//獲取註解
            System.out.println(annotation.datasourceName());
            System.out.println(annotation.sequence());
        }
    }

    private void handleMethodAnnotation() throws NoSuchMethodException {
        Method selectUserNameById = UserService.class.getMethod("selectUserNameById", Integer.class);
        if (selectUserNameById.isAnnotationPresent(DatasourceAnnotation.class)) {
            DatasourceAnnotation annotation = selectUserNameById.getAnnotation(DatasourceAnnotation.class);
            System.out.println(annotation.datasourceName());
            System.out.println(annotation.sequence());
        }
    }


    @Test
    public void test() throws Exception {
        handleFieldAnnotation();
        handleMethodAnnotation();
    }
}

運行結果:生命週期

master
1
salve
2

Process finished with exit code 0

 

註解使用案例二:繼承註解(做用在ElementType.METHOD上 子類的重寫方法是沒法繼承註解的,不重寫方法子類是能夠獲取註解的

註解定義:

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface InheritedAnnotation {
    String name();
}

註解使用:

@InheritedAnnotation(name = "test")
public class UseInheritedAnnotation {
}
public class SubUseInheritedAnnotation extends UseInheritedAnnotation{
}
@Test
    public void test() throws Exception {
        InheritedAnnotation annotation = SubUseInheritedAnnotation.class.getAnnotation(InheritedAnnotation.class);
        System.out.println(annotation.name());
    }

運行結果:

test

Process finished with exit code 0

 

做用在ElementType.METHOD上 子類的重寫方法是沒法繼承註解的,不重寫方法子類是能夠獲取註解的

public class UseInheritedAnnotation {
    @InheritedAnnotation(name = "methodTest")
    public String test(){
        return "";
    }
}
public class SubUseInheritedAnnotation extends UseInheritedAnnotation{
    @Override
    public String test(){
        return "";
    }
}
@Test
    public void test() throws Exception {
        Method test = SubUseInheritedAnnotation.class.getMethod("test", null);
        InheritedAnnotation annotation = test.getAnnotation(InheritedAnnotation.class);
       
        System.out.println(annotation.name());
    }

運行結果:

java.lang.NullPointerException
    at com.ctj.annotationTest.AnnotationTest.test(AnnotationTest.java:35)

 

三:使用註解的過程當中的注意事項

相關文章
相關標籤/搜索