Java 注解1
比较好的简单说明,菜鸟教程
@Retention
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
/**
* Indicates how long annotations with the annotated type are to
* be retained. If no Retention annotation is present on
* an annotation type declaration, the retention policy defaults to
* {@code RetentionPolicy.CLASS}.
*
* <p>A Retention meta-annotation has effect only if the
* meta-annotated type is used directly for annotation. It has no
* effect if the meta-annotated type is used as a member type in
* another annotation type.
*
* @author Joshua Bloch
* @since 1.5
* @jls 9.6.3.2 @Retention
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
其中 RetationPolicy 是个enum,记录retation的几种情况,运行时,源码和类。
/**
* Annotation retention policy. The constants of this enumerated type
* describe the various policies for retaining annotations. They are used
* in conjunction with the {@link Retention} meta-annotation type to specify
* how long annotations are to be retained.
*
* @author Joshua Bloch
* @since 1.5
*/
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
* 被编译器抛弃,即编译时候就没了
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
* 编译时仍然存在
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*运行时仍然存在
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
Example 运行时仍然存在的注解
注解的定义:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 用于修饰方法
@Target(ElementType.METHOD)
// 运行时 依然会被记住
@Retention(RetentionPolicy.RUNTIME)
public @interface runtime {
// name weight两个属性
String name();
String weight();
}
测试类,里面有个函数,使用这个注解,然后在运行时,调用这个注解,看下注解的信息是否还存在。
public class test1 {
// 被测试的方法,使用注解 runtime,并且对name和weight 进行赋值
@runtime(name="I am Peter", weight = "Weight 80kg")
public static void runtime_func(String name, String weight){
System.out.println("name is " +name);
System.out.println("weight is "+ weight);
}
// 无注解的方法
public void func(){
System.out.println("ordinate methods");
}
public static void main(String[] args) throws ClassNotFoundException {
//反射 获得类 对象
Class<?> annotation = Class.forName("test1");
System.out.println("class name: "+annotation.toString());
// 获得类中的所有方法
Method[] ms = annotation.getMethods();
for (Method m:ms
) {
System.out.println("method name: "+m.getName());
// 实例化 : 类中 类型时 runtime.class 的 annotation
runtime runtiem_an = m.getAnnotation(runtime.class);
if(runtiem_an !=null ) {
try {
// 创建一个对象,执行这个函数,并且使用注解中的属性值
m.invoke(new test1(),runtiem_an.name(),runtiem_an.weight());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
打印输出结果
class name: class test1
method name: main
method name: runtime_func
annotaoton nameI am Peter
name is I am Peter
weight is Weight 80kg
method name: func
method name: wait
method name: wait
method name: wait
method name: equals
method name: toString
method name: hashCode
method name: getClass
method name: notify
method name: notifyAll
可以看到,运行时,注解仍然是存在的。
如果将runtime换成source或者class,run程序,得到的结果是:
class name: class test1
method name: main
method name: func
method name: runtime_func
method name: wait
method name: wait
method name: wait
method name: equals
method name: toString
method name: hashCode
method name: getClass
method name: notify
method name: notifyAll