注解
- 定义一个注解
public @interface MyAnno {
}
- 将注解遍历再反编译
- 注解的本质上就是一个接口,该接口默认继承Annotation接口
public interface MyAnno extends java.lang.annotation.Annotation{
}
- 属性:接口中的抽象方法
- 属性的返回值类型只能是下列的类型
- 基本数据类型
- String
- 枚举
- 注解
- 以上类型的数组
- 属性的返回值类型只能是下列的类型
public @interface MyAnno {
String name();
}
- 定义了属性在使用的时候需要给属性赋值
@MyAnno(name = "hello world")
public class Worker {
}
- 如果有默认值,则在使用的时候可以不赋值
public @interface MyAnno {
String name() default "chenminglin";
}
@MyAnno
public class Worker {
}
- 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,指定定义即可
public @interface MyAnno {
String value();
}
@MyAnno("chenminglin")
public class Worker {
}
- 元注解(用于描述注解的注解)
- @Target:描述注解能够作用的位置
- TYPE:可以作用于方法撒花姑娘
- METHOD:可以作用于方法上
- FIFLD:可以作用于成员变量上
- @Retention:描述注解被保留的阶段
- @Documented:描述注解是否被抽取到api文档中
- @Inherited:描述注解是否被子类继承
- @Target:描述注解能够作用的位置
@Target(value = {ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
@Documented
@Inherited
public @interface MyAnno1 {
}
-
在程序中使用(解析)注解,获取注解中定义的属性值
-
自定义注解
/**
* 描述需要执行的类名,和方法名
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro {
String className();
String methodName();
}
- Demo01.java
public class Demo01 {
public void show(){
System.out.println("demo01 -> show()");
}
}
- 使用注解
@Pro(className = "annoDemo.Demo01",methodName = "show")
public class ReflectTest {
public static void main(String[] args) throws Exception {
//1.获取改类的字节码文件对象
Class<ReflectTest> reflectTestClass = ReflectTest.class;
//2.获取上边的注解对象,其实就是在内存中生成了一个该注解接口的子类实现对象
Pro annotation = reflectTestClass.getAnnotation(Pro.class);
//3.调用注解对象定义的抽象方法,获取返回值
String className = annotation.className();
String methodName = annotation.methodName();
//4.使用返回执行show方法
Class aClass = Class.forName(className);
Object o = aClass.newInstance();
Method method = aClass.getMethod(methodName);
method.invoke(o);
}
}
-
Demo,使用注解编写一个框架,添加注解则可以输出哪些方法存在异常
-
注解类
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Check {
}
- 计算类,使用注解
/**
* 计算器类
*/
public class Calculator {
@Check
public int add(){
return 1 + 1;
}
@Check
public int div() {
return 1 / 0;
}
}
- 框架,检测添加注解的方法时候有异常
public class TestCheck {
public static void main(String[] args) throws Exception{
//获取计算器class对象
Class<Calculator> calculatorClass = Calculator.class;
Calculator calculator = calculatorClass.newInstance();
//获取所有的方法
Method[] methods = calculatorClass.getMethods();
//遍历所有方法
for (Method method : methods){
//判断方法时候有@Check注解
if (method.isAnnotationPresent(Check.class)){
try{
method.invoke(calculator);
}catch (Exception e){
System.out.println("方法:"+method.getName()+" 出现异常 ---> " + e.getCause().getClass().getSimpleName());
System.out.println("异常原因:" + e.getCause().getMessage());
}
}
}
}
}
- 控制台输出
方法:div 出现异常 ---> ArithmeticException
异常原因:/ by zero