Java教程 - Java注解
注解将补充信息嵌入源文件中。注解不会更改程序的语义。
通过基于接口的机制创建注解。
以下代码声明了一个名为 MyAnno
的注解:
// A simple annotation type. @interface MyAnno { String str(); int val(); }
@
在关键字接口之前。所有注解仅具有方法声明。注解不能包含extends子句。
注意
所有注解类型自动扩展注解接口。注解接口是所有注解的超级接口。注解接口在java.lang.annotation包中声明。
任何类型的声明都可以具有与其相关联的注解。例如,可以注解类,方法,字段,参数和枚举常量。注解也可以注解。在所有情况下,注解在声明的其余部分之前。
应用注解时,您可以向其成员提供值。例如,下面是一个应用于类的 MyAnno
示例:
// Annotate a method. @MyAnno(str = "Annotation Example", val = 100) public class Main{}
此注解与类Main链接。
Java注解保留策略
保留策略确定在什么时候丢弃注解。
Java定义了三个这样的策略:SOURCE,CLASS和RUNTIME。
- SOURCE仅保留在源文件中,并在编译期间被丢弃。
- CLASS在编译期间存储在.class文件中。 它在运行时不能通过JVM。
- RUNTIME存储在.class文件中,并可在运行时通过JVM使用。
通过使用Java的内置注解之一为注解指定保留策略:
@Retention
其一般形式如下所示:
@Retention(retention-policy)
retention-policy必须是 SOURCE
, CLASS
和 RUNTIME
之一。
默认策略为 CLASS
。
以下代码将保留策略指定为RUNTIME。
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @interface MyAnno { String str(); int val(); }
如何通过使用反射在运行时获取注解。
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; // An annotation type declaration. @Retention(RetentionPolicy.RUNTIME) @interface MyAnno { String str(); int val(); } public class Main { @MyAnno(str = "Annotation Example", val = 100) public static void myMeth() { Main ob = new Main(); try { Class c = ob.getClass(); Method m = c.getMethod("myMeth"); MyAnno anno = m.getAnnotation(MyAnno.class); System.out.println(anno.str() + " " + anno.val()); } catch (NoSuchMethodException exc) { System.out.println("Method Not Found."); } } public static void main(String args[]) { myMeth(); } }
上面的代码生成以下结果。
Java注解反射
您可以获取具有与某个关联的RUNTIME保留的所有注解项目,通过调用该项目的getAnnotations()。
它有这种一般形式:
Annotation[ ] getAnnotations( )
以下代码显示了如何从类中获取注解。
import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; @Retention(RetentionPolicy.RUNTIME) @interface MyAnno { String str(); int val(); } @Retention(RetentionPolicy.RUNTIME) @interface What { String description(); } @What(description = "An annotation") @MyAnno(str = "Meta2", val = 99) public class Main { @What(description = "test method") @MyAnno(str = "Testing", val = 100) public static void myMeth() throws Exception { Main ob = new Main(); Annotation annos[] = ob.getClass().getAnnotations(); System.out.println("All annotations for Meta2:"); for (Annotation a : annos) { System.out.println(a); } Method m = ob.getClass().getMethod("myMeth"); annos = m.getAnnotations(); for (Annotation a : annos) { System.out.println(a); } } public static void main(String args[]) throws Exception { myMeth(); } }
上面的代码生成以下结果。
Java注解默认值
您可以给注解成员默认值。如果在应用注解时未指定值,那么将使用这些默认值。
通过向成员声明添加默认子句来指定默认值。
它有这种一般形式:
type member( ) default value;
这里是 @MyAnno
重写为包括默认值:
@Retention(RetentionPolicy.RUNTIME) @interface MyAnno { String str() default "Testing"; int val() default 9000; }
如果需要,可以给出任一值或两者。因此,以下是可以使用@MyAnno的四种方式:
@MyAnno() // both str and val default @MyAnno(str = "string") // val defaults @MyAnno(val = 100) // str defaults @MyAnno(str = "Testing", val = 100) // no defaults
以下程序演示了在注解中使用默认值。
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; @Retention(RetentionPolicy.RUNTIME) @interface MyAnno { String str() default "Testing"; int val() default 1; } public class Main { @MyAnno() public static void myMeth() throws Exception{ Main ob = new Main(); Class c = ob.getClass(); Method m = c.getMethod("myMeth"); MyAnno anno = m.getAnnotation(MyAnno.class); System.out.println(anno.str() + " " + anno.val()); } public static void main(String args[]) throws Exception{ myMeth(); } }
上面的代码生成以下结果。