[Java] 注解
背景
- 一种数据类型,和class平级
- JDK 1.5 后可用
- 类比:贴标签
- 注解是用来解释代码的元数据,但不是注解的代码本身的一部分,对代码运行效果没有直接影响
- 提取和处理Annotation的代码统称APT(Annotation Proccesing Tool)
应用
- 提供信息给编译器:检查错误信息
- 编译阶段处理:生成代码,Html文档等
- 运行时处理:注解在运行时接收代码提取
基本内置注解
- @Override:重写父类方法。如果父类没有该方法则编译无法通过
- @SuppressWarning:忽略警告信息
- @SafeVarargs:去掉使用可变数量参数,参数类型是泛型T时出现的警告
- @FunctionalInterface:约定函数接口
自定义注解
- 注解类型:@interface
- 创建注解:public @interface JDBCConfig
- 注解元素:String ip();
- 通过反射,获取注解对象
- 通过class对象的isAnnotationPresent()方法,判断是否应用了某个注解
- 通过class对象的getAnnotation(),获取Annotation对象
- 拿到注解对象,通过其方法,获取注解元素的值
- 注解只有成员变量,没有方法
- 注解的成员变量在注解定义中以“无形参方法”形式声明
- 方法名定义了成员变量的名字,返回值定义了成员变量的类型
- 使用时为属性赋值(value = " "),多个属性间用 , 隔开
- 属性的类型必须是8中数据类型,或类、接口、注解及其数组
- 利用 default 为注解的属性设置默认值
元注解
- 元数据(metadata):为其他数据提供信息的数据
- @Target({METHOD,TYPE}):此注解可以使用在方法、类、接口上,不能放在属性位置
- @Retention(RetentionPolicy.RUNTIME):运行时注解,运行起来才可获得注解中信息,而不像@Override编译时就可获取
- @Inherited:可被子类继承
- @Documented:执行javadoc时,会生成相关文档
- @Repeatable:可重复,注解的值可同时取多个
例1:
TestAnnotation.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package Annotation; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 @Target(ElementType.TYPE) 9 @Retention(RetentionPolicy.RUNTIME) 10 public @interface TestAnnotation { 11 12 int id() default -1; 13 14 String msg() default "Hi"; 15 16 }
Test.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import Annotation.TestAnnotation; 2 3 @TestAnnotation() 4 public class Test { 5 6 public static void main(String[] args) { 7 8 boolean hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class); 9 10 if ( hasAnnotation ) { 11 TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class); 12 13 System.out.println("id:"+testAnnotation.id()); 14 System.out.println("msg:"+testAnnotation.msg()); 15 } 16 } 17 }
例2:
MyRequestMapping
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.lang.annotation.*; 2 3 @Target({ ElementType.TYPE, ElementType.METHOD }) 4 @Retention(RetentionPolicy.RUNTIME) 5 @Documented 6 public @interface MyRequestMapping { 7 String value(); // 这是注解的一个属性字段,也就是在使用注解时填写在括号里的参数 8 }
Test
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class Test { 2 public static void main(String[] args) { 3 Class<?> c = TestController.class; 4 MyRequestMapping baseRequestMapping = c.getAnnotation(MyRequestMapping.class); 5 System.out.println(baseRequestMapping.value()); // 输出value的值 6 } 7 }
TestController
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @MyRequestMapping("/test") 2 public class TestController { 3 public void test() { 4 System.out.println("进入Test方法"); 5 } 6 }
输出:/Test
参考
秒懂,Java 注解 (Annotation)你可以这样学
https://blog.csdn.net/briblue/article/details/73824058
自定义注解
https://how2j.cn/k/annotation/annotation-customize/1056.html#nowhere