注解就是那些插入到代码中使用其它工具可以对其进行处理的标签。注解不会改变程序的编译方式,Java编译器对于包含注解和不包含注解的代码会生成相同的JVM指令。
使用场景:
附属文件的自动生成,例如部署描述符或bean信息类;
测试、日志、事务语义等代码的自动生成。
public void MyClass{ @Test public void checkRandomInsertions(); }
@Test 当作一个修饰符(public static),注解本身不会做任何事情,它需要工具支持才会有用。
@Test(timeout="1000")可以定义成包含元素的形式
注解可以用于方法、类、成员、局部变量
每个注解都必须通过注解接口进行定义。
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Test { long timeout() default 0l; }
注解使用反射实现示例:
public class ActionListenerInstaller {
public static void processAnnotations(Object obj) throws NoSuchMethodException,
InvocationTargetException {
try {
//传入调用对象class
Class<?> cl = obj.getClass();
//获取所有方法
for (Method m : cl.getDeclaredMethods()) {
//是否有ActionListenerFor注解
ActionListenerFor a = m.getAnnotation(ActionListenerFor.class);
if (a != null) {
//取出调用对象方法对应域的值
Field field = cl.getDeclaredField(a.source());
field.setAccessible(true);
//调用代理反射
addListener(field.get(obj), obj, m);
}
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public static void addListener(Object source, final Object param, final Method m)
throws SecurityException,
NoSuchMethodException,
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException {
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method mm, Object[] args) throws Throwable {
return m.invoke(param);
}
};
Object listener = Proxy.newProxyInstance(null,
new Class[] { java.awt.event.ActionListener.class }, handler);
Method adder = source.getClass().getMethod("addActionLister", ActionListenerFor.class);
adder.invoke(source, listener);
}
}
@Target(ElementType.METHOD)//适用于方法
@Retention(RetentionPolicy.RUNTIME)//运行时注解
@interface ActionListenerFor {
//元素,相当于方法声明,不能有参数、不能是泛型,不能throw
String source();
}
标记注解,取默认值;单值注解,只有一个元素
注解项说明:
@target元注解表示可以用于哪些项上:
@Retention元注解表示一条注解可以保留多长时间:
源代码级注解
字节码工程,在加载时刻修改类(BCEL)