重复注解

Java8以前,同一个程序元素前最多只能使用一相同类型的注解;如果需要在同一个元素前使用多个相同类型的注解,则必须使用注解"容器"。例如在Struts开发中,有时需要在 Action 类上使用多个@Result注解。在 Java8 以前只能写成如下形式:
@Results({
@Result(name="failure", location="failed.jsp"),
@Result(name="success ", location ="succ.jsp")
})
public Acton FooAction{ ... }

java8以后可以这样写

@Result(name="failure", location="failed.jsp"),
@Result(name="success ", location ="succ.jsp")
public Acton FooAction{ ... }

可重复注解的开发流程

1,首先定义我们需要重复的注解(@Repeatable(ActionTodos.class)就表示我们的注解是可重复的,并且重复的容器是ActionTodos

package com.zmd.repeatAnotation;

import java.lang.annotation.*;

/**
* @ClassName ActionTodo
* @projectName: object1
* @author: Zhangmingda
* @description: 可重复注解
* date: 2021/5/19.
*/
//@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(ActionTodos.class)
public @interface ActionTodo {
String actionListenerName();
}
2,容器注解定义:

package com.zmd.repeatAnotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @ClassName ActionTodos
* @projectName: object1
* @author: Zhangmingda
* @description: 容器注解
* date: 2021/5/19.
*/
//容器
@Retention(RetentionPolicy.RUNTIME)
//@Target(ElementType.TYPE)
public @interface ActionTodos {
ActionTodo[] value();
}

3,具体的使用:

package com.zmd.repeatAnotation;

import javax.swing.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field; /**
* @ClassName UseRepeatable
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/19.
*/
@ActionTodo(actionListenerName = "打鸟")
@ActionTodo(actionListenerName = "掏蛋")
@ActionTodo(actionListenerName = "煮着吃")
public class UseRepeatable {
@ActionTodo(actionListenerName = "打鸟")
@ActionTodo(actionListenerName = "掏蛋")
@ActionTodo(actionListenerName = "煮着吃")
private static JButton okButton = new JButton("一石N鸟");
public static void main(String[] args) throws NoSuchFieldException {
/**
* 获取注解容器
*/
Annotation[] annotations = UseRepeatable.class.getAnnotations();
for (Annotation annotation : annotations){ //获取所有注解,包含容器注解
System.out.println(annotation); //获取所有注解,包含容器注解
} Field okbtnField = UseRepeatable.class.getDeclaredField("okButton");
Annotation[] actions = okbtnField.getAnnotations(); //获取所有注解,包含容器注解
//ActionTodo[] actions = okbtnField.getAnnotationsByType(ActionTodo.class); //可重复注解
for (Annotation actionTodo :actions) {
System.out.println(actionTodo);
}
/**
* 获取注解类的重复注解
*/
ActionTodo[] actionTodos = UseRepeatable.class.getAnnotationsByType(ActionTodo.class);
for (ActionTodo actionTodo : actionTodos){
System.out.println(actionTodo);
}
/**
* 获取属性(类变量)的重复注解
*/
//获取变量反射对象
Field[] fields = UseRepeatable.class.getDeclaredFields();
//循环判断
for (Field field:fields){
field.setAccessible(true);
//是否被容器注解修饰
if (field.isAnnotationPresent(ActionTodos.class)){
//获取注解列表
ActionTodo[] actionTodos1 = field.getAnnotationsByType(ActionTodo.class);
for (ActionTodo actionTodo:actionTodos1){
System.out.println(actionTodo);
}
}
}
}
}

测试使用输出

@com.zmd.repeatAnotation.ActionTodos(value={@com.zmd.repeatAnotation.ActionTodo(actionListenerName="打鸟"), @com.zmd.repeatAnotation.ActionTodo(actionListenerName="掏蛋"), @com.zmd.repeatAnotation.ActionTodo(actionListenerName="煮着吃")})
@com.zmd.repeatAnotation.ActionTodos(value={@com.zmd.repeatAnotation.ActionTodo(actionListenerName="打鸟"), @com.zmd.repeatAnotation.ActionTodo(actionListenerName="掏蛋"), @com.zmd.repeatAnotation.ActionTodo(actionListenerName="煮着吃")})
@com.zmd.repeatAnotation.ActionTodo(actionListenerName="打鸟")
@com.zmd.repeatAnotation.ActionTodo(actionListenerName="掏蛋")
@com.zmd.repeatAnotation.ActionTodo(actionListenerName="煮着吃")
@com.zmd.repeatAnotation.ActionTodo(actionListenerName="打鸟")
@com.zmd.repeatAnotation.ActionTodo(actionListenerName="掏蛋")
@com.zmd.repeatAnotation.ActionTodo(actionListenerName="煮着吃")

 

java 编程基础 注解 :可重复的注解的更多相关文章

  1. Java入门——(1)Java编程基础

    Java入门--(1)Java编程基础 第二章 Java编程基础   JAVA 代码的基本格式: 修饰符 class 类名{ 程序代码 }   2.1关键字:赋予了特殊含义的单词.   2.2标识符: ...

  2. Java编程基础——流程控制

    Java编程基础——流程控制 摘要:本文主要介绍Java编程中的流程控制语句. 分类 流程控制指的是在程序运行的过程中控制程序运行走向的方式.主要分为以下三种: 顺序结构:从上到下依次执行每条语句操作 ...

  3. Java编程基础——标识符和关键字

    Java编程基础——标识符和关键字 摘要:本文主要介绍标识符和关键字. 标识符 是什么 Java语言中,为各种变量.方法.类和包等起的名字,统统称之为Java标识符. 命名规则 ◆ 应以字母.下划线. ...

  4. Java开发知识之Java编程基础

    Java开发知识之Java编程基础 一丶Java的基础语法 每个语言都有自己的语法规范.例如C++ 入口点是main. 我们按照特定格式编写即可. Java也不例外. Java程序的语法规范就是 Ja ...

  5. java编程基础二进制

    0.java编程基础 01.二进制(原码,反码,补码) 02.位运算 03.移位运算符 二进制 原码,反码,补码 1.基本概念 二进制是逢2进位的进位制,0,1是基本算符. 现在的电子计算机技术全部使 ...

  6. Java编程基础-面向对象(中)

    本章承接Java编程基础-面向对象(上)一文. 一.static关键字 在java中,定义了一个static关键字,它用于修饰类的成员,如成员变量.成员方法以及代码块等,被static修饰的成员具备一 ...

  7. Java编程基础——数组和二维数组

    Java编程基础——数组和二维数组 摘要:本文主要对数组和二维数组进行简要介绍. 数组 定义 数组可以理解成保存一组数的容器,而变量可以理解为保存一个数的容器. 数组是一种引用类型,用于保存一组相同类 ...

  8. Java编程基础——运算符和进制

    Java编程基础——运算符和进制 摘要:本文主要介绍运算符和进制的基本知识. 说明 分类 Java语言支持如下运算符: ◆ 算术运算符:++,--,+,-,*,/,%. ◆ 赋值运算符:=,+=,-= ...

  9. Java编程基础——常量变量和数据类型

    Java编程基础——常量变量和数据类型 摘要:本文介绍了Java编程语言的常量变量和数据类型. 常量变量 常量的定义 一块内存中的数据存储空间,里面的数据不可以更改. 变量的定义 一块内存中的数据存储 ...

随机推荐

  1. 【玩具】使用Python自动化发送微信消息进行订水

    事情是这样的,我知道淘宝上有卖一种USB接口的大按钮,估计是给工厂或者医院之类的场景设计的,样子长这样: 然后我就一直挺想搞一个的,不为别的,就是玩,但是想来想去也没想到这玩意儿对我而言能有啥用途,就 ...

  2. Codeforces 1208F - Bits And Pieces(高维前缀和)

    题面传送门 题意:求 \(\max\limits_{i<j<k}a_i|(a_j\&a_k)\). \(1\leq n \leq 10^6,1\leq a_i\leq 2\time ...

  3. [R报错] Kruskal-wallis test 所有组的层次都必需是有限的

    做了个两组间的Kruskal-wallis检验,出现如下错误: 对应的英文版本错误为: All group levels must be finite is.finite(data$type)一下果然 ...

  4. R 语言实战-Part 5-2笔记

    R 语言实战(第二版) part 5-2 技能拓展 ----------第21章创建包-------------------------- #包是一套函数.文档和数据的合集,以一种标准的格式保存 #1 ...

  5. 【R】clusterProfiler的GO/KEGG富集分析用法小结

    前言 关于clusterProfiler这个R包就不介绍了,网红教授宣传得很成功,功能也比较强大,主要是做GO和KEGG的功能富集及其可视化.简单总结下用法,以后用时可直接找来用. 首先考虑一个问题: ...

  6. HTML三层界面显示

    1.效果示意图 2.主要标签属性 3.实现代码 1.效果示意图 要实现类似如下效果:点击"大模态框",中间出现一层遮盖整个页面的半透明页面,最上面出现"Large mod ...

  7. 内网穿透—使用 frp 实现内外网互通

    前言 什么是内网穿透? 内网穿透,又叫 NET 穿透,是计算机用语.用通俗的说法就是你家里的个人电脑,可以直接被外网的人访问.例如你在公司,不通过远程工具,直接也可以访问到家里的电脑(本文章特指 we ...

  8. 分配器——allocators

    任何容器的构建都离不开分配器,分配器顾名思义就是分割配置内存资源的组件,分配器的效率直接影响力容器的效率. operator new()和malloc() C/C++底层都是通过malloc()调用系 ...

  9. C++11的auto自动推导类型

    auto是C++11的类型推导关键字,很强大 例程看一下它的用法 #include<vector> #include<algorithm> #include<functi ...

  10. Oracle中的索引

    1.Oracle 索引简介      在Oracle数据库中,存储的每一行数据都有一个rowID来标识.当Oracle中存储着大量的数据时,意味着有大量的rowID,此时想要快速定位指定的rowID, ...