注解是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)