註解是jdk5引入的新特性,註解至關於增長了一個配置,當咱們使用註解時,咱們能夠經過反射獲取註解從而獲取相關的配置,方便咱們在代碼層面作一些操做。java
包 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
@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
註解定義:
@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
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)