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) + "个方法,其中:\n" + "失败了:"
+ failed + "个,\n" + "成功了:" + 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个!
Java基础教程——解析注解的更多相关文章
- Java基础教程:注解
Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...
- Java基础教程(16)--注解
一.注解基础知识 1.注解的格式 最简单的注解就像下面这样: @Entity @符号指示编译器其后面的内容是注解.在下面的例子中,注解的名称为Override: @Override void ...
- Java基础教程(18)--继承
一.继承的概念 继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...
- Java基础教程(25)--I/O
一.I/O流 I/O流表示输入源或输出目标.流可以表示许多不同类型的源和目标,例如磁盘文件.设备.其他程序等. 流支持许多不同类型的数据,包括字节.原始数据类型.字符和对象等.有些流只传递数据 ...
- Java基础教程:IDEA单元测试
Java基础教程:IDEA单元测试 环境配置 使用idea IDE 进行单元测试,首先需要安装JUnit 插件. 安装JUnit插件步骤 File-->settings-->Plguins ...
- Java基础笔记 – Annotation注解的介绍和使用 自定义注解
Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 | 被围观 25,969 views+ 1.Anno ...
- Java基础教程(12)--深入理解类
一.方法的返回值 当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...
- Java基础教程:网络编程
Java基础教程:网络编程 基础 Socket与ServerSocket Socket又称"套接字",网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个s ...
- Java基础教程(5)--变量
一.变量 1.变量的定义 正如上一篇教程<Java基础教程(4)--面向对象概念>中介绍的那样,对象将它的状态存在域中.但是你可能仍然有一些疑问,例如:命名一个域的规则和惯例是什么?除 ...
随机推荐
- 【转】Setting up SDL Extension Libraries on Windows
FROM: http://lazyfoo.net/tutorials/SDL/06_extension_libraries_and_loading_other_image_formats/window ...
- 【转】Setting up SDL on Windows
FROM: http://lazyfoo.net/tutorials/SDL/01_hello_SDL/windows/index.php Setting up SDL on Windows Last ...
- 冷饭新炒:理解断路器CircuitBreaker的原理与实现
前提 笔者之前在查找Sentinel相关资料的时候,偶然中找到了Martin Fowler大神的一篇文章<CircuitBreaker>.于是花了点时间仔细阅读,顺便温习一下断路器Circ ...
- Docker学习—DockerFile
前言: 上一篇文章简单使用了docker 拉取镜像.启动容器.编译镜像:其中编译镜像时,使用到了Dockerfile,那么接下来我们就详细的来说说Dockerfile DockerFile是什么: D ...
- 专题二:redis的数据类型之string
一.redis的数据存储格式 redis本身是一个Map,其中所有的数据都是采用 "key:value"的方式进行存储的. 我们说的数据类型是数据存储的类型,也就是对应下图的val ...
- CSS中的position属性笔记
一般有5个属性,分别是:static,absolute,relative,fixed,inherit static 自然定位:这个是默认值,没有定位,再设置top,rignt,bottom,left会 ...
- Android 视频播放器 NurVideoPlayer ()
我在实战项目中用了它. 更新了2.x.x版本ijkplayer的封装 支持屏幕滑动--滑动时间,亮度,声音,进度,支持全屏-单屏,双击暂停--继续,锁定屏幕,支持HTTP和https,也可以控制声道( ...
- leetcode6:binary-tree-postorder-traversal
题目描述 求给定的二叉树的后序遍历. 例如: 给定的二叉树为{1,#,2,3}, 1↵ ↵ 2↵ /↵ 3↵ 返回[3,2,1]. 备注:用递归来解这道题太没有新意了,可以给出迭代的解法么? Give ...
- layui table表格详解
上次做table有些东西 忘记了 这次当作来个分析总结一下 跟大家共同学习 闲话不多说 直接上例子 代码: <form id="form1" runat="s ...
- uni-app 动态控制下拉刷新
扫码查看原文,搜索uni-app 动态控制下拉刷新: 前置条件: 开发环境:windows 开发框架:uni-app , H5+,nativeJS 编辑器:HbuilderX 2.8.13 4.兼容版 ...