Person类
1 package day2_17; 2 3 /** 4 * @Author Tianhao 5 * @create 2021-02-17-13:35 6 */ 7 8 9 public class Person { 10 11 public void eat() { 12 System.out.println("今天是2021年正月初六"); 13 } 14 }
自定义 Anno注解
1 package day2_17; 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 /** 9 * 10 通过反编译 javap Anno.class 11 得到: 12 public interface Anno extends java.lang.annotation.Annotation{ 13 public abstract java.lang.String className(); 14 public abstract java.lang.String methodName(); 15 } 16 17 由此可知,注解类本质上就是一个接口,继承于java.lang.annotation.Annotation接口 18 其属性实质上就是抽象方法 19 属性值就是抽象方法的返回值 20 21 22 * 23 * 24 * @Author Tianhao 25 * @create 2021-02-17-13:30 26 */ 27 28 29 //元注解 30 @Target(ElementType.TYPE)//定义注解可以作用在类上 31 @Retention(RetentionPolicy.RUNTIME)//定义注解保留到运行时 32 public @interface Anno { 33 //属性列表 34 String className(); 35 String methodName(); 36 }
测试: AnnoTest类
1 package day2_17; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 6 /** 7 * 解析注解,获取类信息,并执行其对象的方法 8 * 9 * @Author Tianhao 10 * @create 2021-02-17-13:29 11 */ 12 13 @Anno(className = "day2_17.Person",methodName = "eat") 14 public class AnnoTest { 15 16 public static void main(String[] args) { 17 //解析注解 18 //1.获取该类的字节码文件对象 19 Class<AnnoTest> annoTestClass = AnnoTest.class; 20 //2.获取该类上面的注解类对象 21 //其实就是在内存中生成了一个该注解接口的匿名实现类对象 22 /* 23 new Anno(){ 24 public String className(){ 25 return "day2_17.Person"; 26 } 27 28 public String methodName(){ 29 return "eat"; 30 } 31 } 32 33 */ 34 35 Anno anno = annoTestClass.getAnnotation(Anno.class); 36 //3.获取注解类对象的属性值 37 //注解实现类对象调用实现方法,获取返回值就是属性值 38 String className = anno.className(); 39 String methodName = anno.methodName(); 40 //打印属性值看看 41 System.out.println(className);//day2_17.Person 42 System.out.println(methodName);//eat 43 44 45 //通过反射机制,或者类对象和方法对象,并调用相应的方法 46 try { 47 //加载该类进内存 48 Class clazz = Class.forName(className); 49 //创建对象 50 Object obj = clazz.newInstance(); 51 //获取方法对象 52 Method method = clazz.getMethod(methodName); 53 //执行方法 54 method.invoke(obj);//今天是2021年正月初六 55 } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) { 56 e.printStackTrace(); 57 } 58 59 } 60 61 }