java 编程基础 注解 :可重复的注解

重复注解

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 </span>= UseRepeatable.<span style="color: rgba(0, 0, 255, 1)">class</span>.getDeclaredField("okButton"<span style="color: rgba(0, 0, 0, 1)">);
     Annotation[] actions </span>= okbtnField.getAnnotations(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取所有注解,包含容器注解
     </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">ActionTodo[] actions = okbtnField.getAnnotationsByType(ActionTodo.class); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可重复注解</span>
     <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (Annotation actionTodo :actions) {
         System.out.println(actionTodo);
     }
     </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
      * 获取注解类的重复注解
      </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
     ActionTodo[] actionTodos </span>= UseRepeatable.<span style="color: rgba(0, 0, 255, 1)">class</span>.getAnnotationsByType(ActionTodo.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
     </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (ActionTodo actionTodo : actionTodos){
         System.out.println(actionTodo);
     }
     </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
      * 获取属性(类变量)的重复注解
      </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
     <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取变量反射对象</span>
     Field[] fields = UseRepeatable.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">.getDeclaredFields();
     </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">循环判断</span>
     <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (Field field:fields){
         field.setAccessible(</span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
         </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">是否被容器注解修饰</span>
         <span style="color: rgba(0, 0, 255, 1)">if</span> (field.isAnnotationPresent(ActionTodos.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">)){
             </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取注解列表</span>
             ActionTodo[] actionTodos1 = field.getAnnotationsByType(ActionTodo.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
             </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (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="煮着吃")