注解使用实例

package com.test.collection;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;


import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;


//(元注释后面讲)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)  //定义作用在字段上
@Documented
@interface ActionListenerAnno {
  //该listener成员变量用于保存监听器实现类
  Class<? extends ActionListener> listener();
}


public class TestListener {

  JFrame jf = new JFrame("测试");
  @ActionListenerAnno(listener=OkListener.class)
  private JButton ok = new JButton("确认");
  @ActionListenerAnno(listener=CancelListener.class)
  private JButton cancel = new JButton("取消");
  
  public void init() throws IllegalArgumentException, IllegalAccessException, InstantiationException{
      JPanel jp = new JPanel();
      jp.add(ok);
      jp.add(cancel);
      jf.add(jp);
      //添加监听器
      ButtonActionListener.process(this);
      jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      jf.pack();
      jf.setLocationRelativeTo(null);
      jf.setVisible(true);
  }
  public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InstantiationException {
      new TestListener().init();
  }
}


class OkListener implements ActionListener{
  @Override
  public void actionPerformed(ActionEvent e) {
      System.out.println("确认按钮被点击");
      JOptionPane.showMessageDialog(null, "确认按钮被点击");
  }
}


class CancelListener implements ActionListener{
  @Override
  public void actionPerformed(ActionEvent e) {
      System.out.println("取消按钮被点击");
      JOptionPane.showMessageDialog(null, "取消按钮被点击");
  }
  
}


class ButtonActionListener{
  public static void process(Object obj) throws IllegalArgumentException, IllegalAccessException, InstantiationException{
      Class<? extends Object> clazz = obj.getClass();
      Field[] fields = clazz.getDeclaredFields();
      for(Field f : fields){
          //将指定Field设置成可自由访问的,避免private的Field不能访问
          f.setAccessible(true);
          //获取指定Field的ActionListenerAnno类型的注解
          ActionListenerAnno a = f.getAnnotation(ActionListenerAnno.class);
          // 获取成员变量f的值
          Object fObj = f.get(obj);
          if(a != null && fObj instanceof AbstractButton){
              // 获取a注解里的listner元数据(它是一个监听器类)
              Class<? extends ActionListener> listenerClazz = a.listener();
              // 使用反射来创建listner类的对象
              ActionListener al = listenerClazz.newInstance();
              AbstractButton ab = (AbstractButton)fObj;
              // 为ab按钮添加事件监听器
              ab.addActionListener(al);
          }
      }
  }

}




  • JDK的元Annotation

  JDK除了在java.lang 下提供了3个基本Annotation之外,还在java.lang.annotation包下提供了四个Meta Annotation(元Annotation),这四个Annotation都是用于修饰其他Annotation定义。

  • 使用@Retention

  @Retention只能用于修饰一个Annotation定义,用于指定该Annotation可以保留多长时间,@Retention包含一个RetentionPolicy类型的value成员变量,所以使用@Retention时必须为该value成员变量指定值。

  value成员变量的值只能是如下三个:

    1. RetentionPolicy.CLASS: 编译器将把注释记录在class文件中。当运行Java程序时,JVM不在保留注释,这是默认值。
    2. RetentionPolicy.RUNTIME编译器将把注释记录在class文件中。当运行Java程序时,JVM也会保留注释,程序可以通过反射获取该注释。
    3. RetentionPolicy.SOURCE:  注解仅存在于源码中,在class字节码文件中不包含。
  • 使用@Target

  @Target也是用于修饰一个Annotation定义,它用于指定被修饰Annotation能用于修饰那些程序元素。@Target Annotation也包含一个名为value的成员变量,该成员变量只能是如下几个:

    1. ElementType.ANNOTATION_TYPE: 指定该策略的Annotation只能修饰Annotation。
    2. ElementType.CONSTRUCTOR:  指定该策略的Annotation能修饰构造器。
    3. ElementType.FIELD:  指定该策略的Annotation只能修饰成员变量。
    4. ElementType.LOCAL_VARIABLE:  指定该策略的Annotation只能修饰局部变量。
    5. ElementType.METHOD: 指定该策略的Annotation只能修饰方法。
    6. ElementType.PACKAGE:  指定该策略的Annotation只能修饰包定义。
    7. ElementType.PARAMETER:  指定该策略的Annotation可以修饰参数。
    8. ElementType.TYPE:  指定该策略的Annotation可以修饰类、接口(包括注释类型)或枚举定义。
  • 使用@Documented

  @Documented用于指定该元Annotation修饰的Annotation类将被javadoc工具提取成文档,如果定义Annotation类时使用了@Documented修饰,则所有使用该Annotation修饰的程序元素的API文档中将会包含该Annotation说明。

  • 使用@Inherited

  @Inherited 元 Annotation指定被它修饰的Annotation将具有继承性:如果某个类使用了A Annotation(定义该Annotation时使用了@Inherited修饰)修饰,则其子类将自动具有A注释。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值