• Java基础教程——解析注解


    解析注解

    Java 5开始,java.lang.reflect包下的反射API可以在运行时读取Annotation。

    应用:定义一个自动执行方法的注解,解析注解、通过反射执行方法,替代配置文件。

    package ah.annotation;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    //==============================================
    //注解
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface AutoMethod {
    	String className();
    	String methodName();
    }
    // ==============================================
    // 想要调用的类和方法
    class Cat {
    	public void show() {
    		System.out.println("Cat show");
    	}
    }
    // ==============================================
    // 测试类
    @AutoMethod(className = "ah.annotation.Cat", methodName = "show")
    public class TestParseAnn {
    	public static void main(String[] args) {
    		// 1.获取类的字节码对象
    		Class<TestParseAnn> cls = TestParseAnn.class;
    		// 2.获取注解对象
    		AutoMethod ann = cls.getAnnotation(AutoMethod.class);
    		// 3.调用注解对象的抽象方法,获取返回值
    		String className = ann.className();
    		String methodName = ann.methodName();
    		System.out.println("获取到类名:" + className);
    		System.out.println("获取到方法名:" + methodName);
    		// 使用反射集合调用方法(略)
    	}
    }
    
    获取到类名:ah.annotation.Cat
    获取到方法名:show
    

    例:使用注解进行方法测试

    注解传入的变量:B
    方法public static void ah.AnnoTestExample.m3(java.lang.String)运行失败,异常:java.lang.IllegalArgumentException: 参数出错!
    注解传入的变量:御弟
    --m1--:御弟
    共运行了:2个方法,其中:
    失败了:1个,
    成功了:1个!

    package ah.annotation;
    import java.lang.annotation.*;
    import java.lang.reflect.Method;
    //============================================
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @Documented
    @Inherited
    @interface AnnoTest {
    	// 注解的属性:
    	String name() default "御弟";
    }
    // ============================================
    // 使用自定义注解的类
    class AnnoTestExample {
    	@AnnoTest
    	public static void m1(String _name) {
    		System.out.println("--m1--:" + _name);
    	}
    	public static void m2() {
    		System.out.println("这个方法不测试");
    	}
    	@AnnoTest(name = "B")
    	public static void m3(String _name) {
    		if (_name.equals("B")) {
    			throw new IllegalArgumentException("参数出错!");
    		} else {
    			System.out.println("--m3--:" + _name);
    		}
    	}
    }
    // ============================================
    // APT:Annotation Processor Test(注解处理工具)
    class APT {
    	public static void process(String className) throws ClassNotFoundException {
    		int passed = 0;
    		int failed = 0;
    		Class<?> _class = Class.forName(className);
    		for (Method m : _class.getMethods()) {
    			// 如果该方法使用了@注解
    			if (m.isAnnotationPresent(AnnoTest.class)) {
    				// 获取注解中的变量
    				AnnoTest ann = m.getAnnotation(AnnoTest.class);
    				String name = ann.name();
    				System.out.println(" 注解传入的变量:" + name);
    				try {
    					// 调用m方法
    					m.invoke(_class, name);
    					// *方法无参数可直接传入null:
    					// m.invoke(null);
    					// 测试成功,passed计数器加1
    					passed++;
    				} catch (Exception ex) {
    					System.out.println("方法" + m + "运行失败,异常:" + ex.getCause());
    					// 测试出现异常,failed计数器加1
    					failed++;
    				}
    			}
    		}
    		// 统计测试结果
    		System.out.println("共运行了:" + (passed + failed) + "个方法,其中:
    " + "失败了:"
    				+ failed + "个,
    " + "成功了:" + passed + "个!");
    	}
    }
    /**
     * 测试类,主方法
     */
    public class TestMyAnnotation {
    	public static void main(String[] args) throws ClassNotFoundException {
    		String _包类名 = "ah.annotation.AnnoTestExample";
    		APT.process(_包类名);
    	}
    }
    
     注解传入的变量:B
    方法public static void ah.annotation.AnnoTestExample.m3(java.lang.String)运行失败,异常:java.lang.IllegalArgumentException: 参数出错!
     注解传入的变量:御弟
    --m1--:御弟
    共运行了:2个方法,其中:
    失败了:1个,
    成功了:1个!
    
  • 相关阅读:
    webpack搭建react+ts+eslint项目
    eslint规则详解
    js源码-自定义数组的pop和shift方法
    js源码-数组中的push()和unshift()方法的源码实现
    mac 下载MySQL后,需要这样打开
    react-(错误代码#31----Minified React error #31)
    人生反思:养殖场的猪该如何度过猪生?
    人生反思:做一头拉磨的驴子还是千里马?
    地图轨迹内插采集点
    同时支持回调和Promise的函数-callbackOrPromiseFn
  • 原文地址:https://www.cnblogs.com/tigerlion/p/11182854.html
Copyright © 2020-2023  润新知