1.什么是注解
注解是那些插入到源代码中使用其他工具可以对其进行处理的标签。下面就是一个注解的使用示例,注解事件处理器。
1 package cn.sp.chapter10.annotation;
2
3 import javax.swing.*;
4 import java.awt.*;
5
6 /**
7 * Created by 2YSP on 2017/12/16.
8 */
9 public class ButtonFrame extends JFrame {
10
11 private static final int DEFAULT_WIDTH = 300;
12 private static final int DEFAULT_HEIGHT = 200;
13
14 private JPanel panel;//面板
15 private JButton yellowButton;
16 private JButton blueButton;
17 private JButton redButton;
18
19 public ButtonFrame(){
20 setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
21 panel = new JPanel();
22 add(panel);
23 yellowButton = new JButton("Yellow");
24 blueButton = new JButton("blue");
25 redButton = new JButton("red");
26
27 panel.add(yellowButton);
28 panel.add(blueButton);
29 panel.add(redButton);
30
31 ActionListenerInstaller.processAnnotations(this);
32 }
33
34 @ActionListenerFor(source = "yellowButton")
35 public void yellowBackground(){
36 yellowButton.setBackground(Color.yellow);
37 }
38
39 @ActionListenerFor(source = "blueButton")
40 public void blueBackground(){
41 blueButton.setBackground(Color.blue);
42 }
43
44 @ActionListenerFor(source = "redButton")
45 public void redBackground(){
46 redButton.setBackground(Color.red);
47 }
48 }
1 package cn.sp.chapter10.annotation;
2
3 import java.awt.event.ActionListener;
4 import java.lang.reflect.Field;
5 import java.lang.reflect.InvocationHandler;
6 import java.lang.reflect.Method;
7 import java.lang.reflect.Proxy;
8
9 /**
10 * Created by 2YSP on 2017/12/16.
11 * 分析注解以及安装行为监听器
12 */
13 public class ActionListenerInstaller {
14
15 /**
16 * Process all ActionListenerFor annotation in the given object
17 *
18 * @param obj an object whose methods may have ActionListenerFor annotations
19 */
20 public static void processAnnotations(Object obj) {
21 try {
22 //获取类
23 Class<?> c1 = obj.getClass();
24 for (Method m : c1.getDeclaredMethods()) {
25 ActionListenerFor a = m.getAnnotation(ActionListenerFor.class);//获取注解
26 if (a != null) {
27 Field f = c1.getDeclaredField(a.source());
28 f.setAccessible(true);//字段私有的 添加权限
29 addListener(f.get(obj),obj,m);// field.get(obj) 返回指定对象上此 Field 表示的字段的值 :yellowButton
30 }
31 }
32 } catch (Exception e) {
33 e.printStackTrace();
34 }
35 }
36
37 /**
38 * Adds an action listener that calls a given method
39 * @param source the event source th which an action listener is added
40 * @param param the implicit parameter of the method that the listener calls
41 * @param m the method that the listener calls
42 * @throws Exception
43 */
44 public static void addListener(Object source,final Object param,final Method m)throws Exception{
45 // yellowButton.addActionListener(new ActionListener() {
46 // @Override
47 // public void actionPerformed(ActionEvent e) {
48 // doSomething();
49 // }
50 // });
51 InvocationHandler handler = new InvocationHandler() {
52 @Override
53 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
54 return m.invoke(param);//执行将按钮背景变色的方法
55 }
56 };
57 //创建代理对象
58 Object listener = Proxy.newProxyInstance(null,new Class[]{java.awt.event.ActionListener.class},handler);
59 Method adder = source.getClass().getMethod("addActionListener", ActionListener.class);
60 adder.invoke(source,listener);
61 }
62 }
1 package cn.sp.chapter10.annotation;
2
3 import java.lang.annotation.ElementType;
4 import java.lang.annotation.Retention;
5 import java.lang.annotation.RetentionPolicy;
6 import java.lang.annotation.Target;
7
8 /**
9 * Created by 2YSP on 2017/12/16.
10 * 自定义注解 P740
11 */
12 @Target(ElementType.METHOD)
13 @Retention(RetentionPolicy.RUNTIME)
14 public @interface ActionListenerFor {
15 String source();
16 }
1 package cn.sp.chapter10.annotation;
2
3 /**
4 * Created by 2YSP on 2017/12/16.
5 */
6 public class test {
7
8 public static void main(String[] args) {
9 ButtonFrame frame = new ButtonFrame();
10 frame.setVisible(true);
11 }
12 }
运行后点击三个按钮可以分别改变其背景色,
@Target和
@Retention是元注解,它们注解了ActionListenerFor注解。
2.注解语法
modify @interface AnnotationName
{
elementDeclartion1
elementDeclartion2
.......
}
其中每个元素声明都可以是以下其中一种形式:
type elementName();
或
type elementName() default value;
所有注解都隐式地扩展自java.lang.annotation.Annotation接口。