java 编程基础:【注解】 提取注解信息,利用自定义注解编写测试类,注解绑定事件
提取注解信息
- Class: 类定义
- Constructor: 构造器定义
- Field: 类的成员变量定义
- Method: 类的方法定义
- Packag: 的包定义
- A getAnnotation(ClassannotationClass): 返回该程序元素上存在的、指定类型的注解,如果该类型的注解不存在,则返回null。
- A getDeclaredAnnotation(Class ann tationClass):Java8新增的方法,获取直接修饰元素的指定类型的注解(不会获取到从父类集成来的注解)
- Annotation[] getAnnotations(): 返回元素上的所有注解
- Annotation[] getDeclaredAnnotations(): 返回直接修饰该程序元素的所有注解(不会获取到从父类集成来的注解)
- boolean isAnnotationPresent(Class annotationClass): 判断该程序元素是否存在指定类型的注解,如果存在则返回true 否则返回 false
- Annotation[] getAnnotationsByType(Class annotationClass): 由于Java8增加了重复注解功能,因此需要使用该方法获取对应元素指定类型的可重复的注解
- Annotation[] getDeclaredAnnotationsByType(Class annotationClass): 同上,java8新增了重复注解功能,需要使用该方法获取直接修饰对应元素指定类型的可重复的注解(不会获取到从父类集成来的注解)
package com.zmd.myAnnotation;
import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) //配置生命周期运行时可以获取到
@Inherited //配置注解的继承性,用了注解的父类,子类默认被修饰
public @interface MyAnnotation {
String name() default "zmd";
int age() default 22;
}
定义一个父类使用注解
package com.zmd.myAnnotation; import java.lang.annotation.Annotation; @MyAnnotation(name = "hehe",age = 1)
public class MyClass {
public static void main(String[] args) {
//判断是否有MyAnnotation注解修饰
System.out.println(MyClass.class.isAnnotationPresent(MyAnnotation.class)); //true
//获取包括继承父类的注解。
Annotation annotation = MyClass.class.getAnnotation(MyAnnotation.class);
if (annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("tag is:" + annotation); //tag is:@com.zmd.myAnnotation.MyAnnotation(name="hehe", age=1)
System.out.println("name is:" + myAnnotation.name()); //name is:hehe
System.out.println("age is:" + myAnnotation.age()); //age is:1
}
}
}
定义子类继承父类获取注解信息
package com.zmd.myAnnotation;
import java.lang.annotation.Annotation; public class MySubClass extends MyClass {
public static void main(String[] args) {
//是不是有MyAnnotation注解修饰
System.out.println(MySubClass.class.isAnnotationPresent(MyAnnotation.class)); //true
//获取指定类型的Annotation
// Annotation annotation = SubClass.class.getAnnotation(MyAnnotation.class);//用这行代码,可以获取到MyAnnotation,因为MyAnnotation是获取所有包括继承性的
Annotation annotation = MySubClass.class.getDeclaredAnnotation(MyAnnotation.class);//用这行代码无法获取到MyAnnotation,因为我们getDeclaredAnnotation方法只能获取到直接修饰该类的注解,不能获取到从父类继承过来的注解
System.out.println(annotation); //null
if (annotation instanceof MyAnnotation) { //false 啥也没输出
System.out.println("tag is " + annotation);
System.out.println("name is " + ((MyAnnotation) annotation).name());
System.out.println("age is " + ((MyAnnotation) annotation).age());
}
}
}
编写测试工具
利用自定义注解标识可测试的方法,编写测试工具类,用于测试那些只标识了可以测试的方法
1、编写自定义注解
package com.zmd.autotestTools; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) //运行时可获取
@Target(ElementType.METHOD) //只能修饰方法
public @interface Testable {
}
2、编写使用注解的类
package com.zmd.autotestTools;
public class MyClass {
@Testable
public static void m1() {};
public static void m2() {};
@Testable
public static void m3() {throw new RuntimeException();};
public static void m4() {};
@Testable
public static void m5() {throw new IllegalArgumentException();};
public static void m6() {};
@Testable
public static void m7() {};
public static void m8() {};
}
3、编写工具类测试 使用注解的类中的方法
package com.zmd.autotestTools; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier; /**
* @ClassName TestMethod
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/18.
*/
public class TestMethod {
public static void test(Class<?> cls) throws IllegalAccessException, InstantiationException {
//获取所有的方法
Method[] methods = cls.getMethods();
//创建一个实例
MyClass myClass = (MyClass) cls.newInstance();
for (Method method : methods){
//如果方法被修饰,意思是可以测试
if (method.isAnnotationPresent(Testable.class)){
//那就测试
try {
//如果是静态方法
if (Modifier.isStatic(method.getModifiers())){
method.invoke(null);
}else {
method.invoke(MyClass.class);
}
System.out.println(method.getName() + "测试成功");
}catch (InvocationTargetException e) {
// e.printStackTrace();
System.err.println(method.getName() + "测试失败");
} }
}
} public static void main(String[] args) throws InstantiationException, IllegalAccessException {
test(MyClass.class);
}
}

注解绑定事件
开发思路:
- 1、定义单独一个处理注解的类,使用此类的静态方法处理给定对象中的所有实例变量。
- 2、自定义注解中定义属性,用于使用注解时传入对应的事件类型。
- 3、窗口Button使用注解,再调用处理注解的类处理窗口中所有实例变量。
1、编写自定义注解
package com.zmd.annotationbindAction; import java.awt.event.ActionListener;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)//运行时可获取
@Target(ElementType.FIELD) //只能修饰类变量实例变量
public @interface ActionListenFor {
Class<? extends ActionListener> value();
}
2、编写绑定事件方法类
package com.zmd.annotationbindAction; import javax.swing.*;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import java.lang.reflect.Type; /**
* @ClassName ProcessesAnnotation
* @projectName: object1
* @author: Zhangmingda
* @description: 处理
* date: 2021/5/18.
*/
public class ProcessesAnnotation {
public static void processes(Object object) throws IllegalAccessException, InstantiationException {
Class<?> cls = object.getClass();
//获取所有属性
Field[] allField = cls.getDeclaredFields();
for (Field field : allField) {
//如果属性被注解修饰
if (field.isAnnotationPresent(ActionListenFor.class)){
//设置可访问
field.setAccessible(true);
//获取对应的注解
ActionListenFor actionListenFor = field.getAnnotation(ActionListenFor.class);
//获取要绑定的事件的Class,创建事件监听器
Class<? extends ActionListener> actionClass = actionListenFor.value();
ActionListener actionListener = actionClass.newInstance();
//将属性转换为button对象绑定事件
AbstractButton button = (AbstractButton) field.get(object);
button.addActionListener(actionListener);
}
}
}
}
2、编写图形化窗口
package com.zmd.annotationbindAction; import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; /**
* @ClassName TestAnnotationBindAction
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/18.
*/
public class TestAnnotationBindAction { //定义窗口需要的基础属性
private JFrame jFrame = new JFrame("测试注解绑定事件"); @ActionListenFor(okAction.class)
private JButton confirmbutton = new JButton("确定"); @ActionListenFor(cancleAction.class)
private JButton canclebutton = new JButton("取消"); private JPanel jPanel = new JPanel(); /**
* 组装窗口
*/
private void start() throws InstantiationException, IllegalAccessException {
jPanel.add(confirmbutton);
jPanel.add(canclebutton);
jFrame.add(jPanel);
jFrame.setLocation(400,300);
jFrame.pack();
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jFrame.setVisible(true);
//使用处理类处理本类所有属性
ProcessesAnnotation.processes(this);
} public static class okAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("点击了确认按钮");
}
}
public static class cancleAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("点击了取消按钮");
}
}
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
new TestAnnotationBindAction().start();
}
}

java 编程基础:【注解】 提取注解信息,利用自定义注解编写测试类,注解绑定事件的更多相关文章
- Java入门——(1)Java编程基础
Java入门--(1)Java编程基础 第二章 Java编程基础 JAVA 代码的基本格式: 修饰符 class 类名{ 程序代码 } 2.1关键字:赋予了特殊含义的单词. 2.2标识符: ...
- java编程基础二进制
0.java编程基础 01.二进制(原码,反码,补码) 02.位运算 03.移位运算符 二进制 原码,反码,补码 1.基本概念 二进制是逢2进位的进位制,0,1是基本算符. 现在的电子计算机技术全部使 ...
- Java编程基础——常量变量和数据类型
Java编程基础——常量变量和数据类型 摘要:本文介绍了Java编程语言的常量变量和数据类型. 常量变量 常量的定义 一块内存中的数据存储空间,里面的数据不可以更改. 变量的定义 一块内存中的数据存储 ...
- Java开发知识之Java编程基础
Java开发知识之Java编程基础 一丶Java的基础语法 每个语言都有自己的语法规范.例如C++ 入口点是main. 我们按照特定格式编写即可. Java也不例外. Java程序的语法规范就是 Ja ...
- Java编程基础-面向对象(中)
本章承接Java编程基础-面向对象(上)一文. 一.static关键字 在java中,定义了一个static关键字,它用于修饰类的成员,如成员变量.成员方法以及代码块等,被static修饰的成员具备一 ...
- Java编程基础——数组和二维数组
Java编程基础——数组和二维数组 摘要:本文主要对数组和二维数组进行简要介绍. 数组 定义 数组可以理解成保存一组数的容器,而变量可以理解为保存一个数的容器. 数组是一种引用类型,用于保存一组相同类 ...
- Java编程基础——流程控制
Java编程基础——流程控制 摘要:本文主要介绍Java编程中的流程控制语句. 分类 流程控制指的是在程序运行的过程中控制程序运行走向的方式.主要分为以下三种: 顺序结构:从上到下依次执行每条语句操作 ...
- Java编程基础——运算符和进制
Java编程基础——运算符和进制 摘要:本文主要介绍运算符和进制的基本知识. 说明 分类 Java语言支持如下运算符: ◆ 算术运算符:++,--,+,-,*,/,%. ◆ 赋值运算符:=,+=,-= ...
- Java编程基础——标识符和关键字
Java编程基础——标识符和关键字 摘要:本文主要介绍标识符和关键字. 标识符 是什么 Java语言中,为各种变量.方法.类和包等起的名字,统统称之为Java标识符. 命名规则 ◆ 应以字母.下划线. ...
随机推荐
- 计算机系统->Hello World的一生 | 程序如何运行
2021年11月27日准备发在基地微信公众号上的推文. 综合了多篇大佬的博客,以及自己已经知道的知识,对一些疑惑进行了现阶段我认为还算满意的解答. 不过又产生了很多疑问: 内存和磁盘的关系 CPU是如 ...
- 柯基数据通过Rainbond完成云原生改造,实现离线持续交付客户
1.关于柯基数据 南京柯基数据科技有限公司成立于2015年,提供一站式全生命周期知识图谱构建和运维.智能应用服务,致力于"链接海量数据,从大数据中挖掘智慧".帮助企业运用知识 ...
- arthas 简单使用
简介 Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱. 官网地址:https://arthas.aliyun.com/ 它可以做什么,以下功能都是直接操作线上跑着的jar包!!! ...
- CF1610F F. Mashtali: a Space Oddysey
我们首先发现有如下性质: 我们不妨先随机定向边,那么我们发现无论我们如何翻转边. 都会对其两端的点,造成 \(2 / 4\) 的影响,所以我们发现如果一个点其和他相连的所有边权和为偶数,则我们不能调整 ...
- CF1463E Plan of Lectures
考虑我们两种操作: 我们把第一种操作在\(x\to y\)连一条权为-1的边. 第二种操作\(x\to y\)连-1,\(y\to x\)连1的边. 当无法操作则是环里有负环. 否则我们把第二种操作涉 ...
- Codeforces 1188E - Problem from Red Panda(找性质+组合数学)
Codeforces 题面传送门 & 洛谷题面传送门 咦,题解搬运人竟是我? 一道很毒的计数题. 先转化下题意,每一次操作我们可以视作选择一种颜色并将其出现次数 \(+k\),之后将所有颜色的 ...
- Atcoder Grand Contest 033 D - Complexity(dp)
Atcoder 题面传送门 & 洛谷题面传送门 首先 \(n^5\) 的暴力非常容易想,设 \(dp_{a,b,c,d}\) 表示以 \((a,b)\) 为左上角,\((c,d)\) 为右下角 ...
- gg=G
1.代码格式化对齐 2.直接按下ESE模式下就可以来执行了
- Java中static关键字声明的静态内部类与非静态内部类的区别
(1)内部静态类不需要有指向外部类的引用.但非静态内部类需要持有对外部类的引用.(2)非静态内部类能够访问外部类的静态和非静态成员.静态类不能访问外部类的非静态成员.他只能访问外部类的静态成员.(3) ...
- Notepad++【远程操作linux文件】
目录 目的 预期效果 操作步骤 1.打开插件 2.安装NppFTP 3.连接远程主机 注意 目的 通过Notepad++远程登录linux主机,修改配置文件 预期效果 在Notepad++上登录lin ...