概念
- 给计算机看
- 作用
- 形成文档
- 程序处理
- 编译检查
内置注解
- @Overide
- @Deprecated
- @SuppressWarning @SuppressWarning("all")
自定义注解
- 格式
- 元注解
- public @interface annotation-name {}
- 本质:是一个接口,继承Annotation接口
- public interface MyAnno extends java.annotation.Annotation{}
- 属性:相当于接口中的抽象方法
- 要求
- 属性的返回值类型
- 基本类型
- String
- 枚举
- 注解
- 以上类型的数组
- 注解使用时属性必须复制,
- 可用default为属性赋默认值 String name() default "zhangsan"
- 如果只有一个属性需要赋值,且名称为value,可以直接赋值
- 数组赋值:如果数组中只有一个数组可以直接写,否则用{}
- 注解赋值: @注解名
- 属性的返回值类型
- 要求
- 元注解
- 描述注解的注解
- @Target:描述注解能够作用的位置
- ElementType.TYPE
- ElementType.METHOD
- ElementType.FIELD
- @Retentation:注解保留阶段
- RetentionPolicy.RUNTIME: 被描述的注解保留在字节码文件中,JVM会读到被描述的注解。
- RetentionPolicy.CLASS: 被描述的注解保留在字节码文件中。
- RetentionPolicy.SOURCE,: Annotations are to be discarded by the compiler.。
- @Document:是否被javaDoc
- @Inherited: 被描述的注解会自动带到子类
- 注解的解析
获取该类的字节码文件
Class<ReflectTest> reflectTest = ReflectTest.class
-
获取上边的注解对象
Pro an =reflectTest.getAnnotation(Pro.class);
其实就是在内存中生成了一个该注解接口的子类实现对象public class ProImpl implements Pro { public String className() { return "my.app" } public String methodName (){ return "methodName" } }
用注解对象中的抽象方法,获取返回值
String className = an.className()
自定义注解实例
- 定义注解
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Check { }
- 使用注解
public class Calculator { @Check public void add() { System.out.println(String.format("The result is %d",(1+2))); } @Check public void sub() { System.out.println(String.format("The result is %d",(1 - 2))); } @Check public void mul() { System.out.println(String.format("The result is %d",(1 * 2))); } @Check public void div() { System.out.println( String.format("The result is %d",(1 / 0))); } }
- 注解解析
public class CheckHandler { public static void main(String[] args) { Calculator cal = new Calculator(); Class<? extends Calculator> calClass = cal.getClass(); Method[] methods = calClass.getMethods(); Arrays.asList(methods).stream() .filter(mth -> mth.isAnnotationPresent(Check.class)) .forEach(mth -> { try { mth.invoke(cal); } catch (Exception e) { System.out.println(e.getCause().getClass().getSimpleName()); System.out.println(e.getCause().getMessage()); } }); } }