转载自:http://www.iteye.com/topic/234330
2.注释
2.1 什么是元数据
2.2 JDK中内置的注释.
2.3 自定义注释
2.3.1 注释的种类
2.3.2 适用的位置
2.3.3 关于参数列表
最近一段时间在整理关于JDK5新特性的资料.发出来与各位分享.如果哪里有问题请指正.谢谢
2.1 什么是元数据:元数据被描述为定义数据的数据.比如我拍一张照片.照片本身是我需要的主体数据.但如果我想知道这张照片是什么时候拍摄的那我的数码相机可以帮我添上年月日时分秒.那对于照片本身来讲这个时间就是描述他的元数据.
JAVA中的元数据(注释)主要用于生成文档,检查代码,或者为运行时需要的功能提供数据.
JAVA中的注释分为两块---数据的提供者和数据的使用者
数据提供者就是我们经常使用的方式.比如这样一个注释@Author(name="yh")我们只提供了这样一个数据并不知道程序会拿他来做什么.
数据使用者是分析这些数据并提供操作的家伙.它得到@Author注释.并且可以得到name属性中的数据,然后用于生成文档或者做其他事情.这些对于数据提供者来说完全是透明的.
2.3 自定义注释:
自定义注释长啥样:
- @Target({ElementType.Method})
- @Retention(RetentionPolicy.RUNTIME)
- public @interface MyAnnotation{
- public String name() default "yh";
- }
@Target({ElementType.Method})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
public String name() default "yh";
}
简单解释一下上面的注释.
@Target:一个标注注释的注释.也可以说是注释的元数据.作用是标注MyAnnotation的适用地点这里标注为方法.也就是说MyAnnotation只能用于标示方法.
我们看一下Target的声明
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.ANNOTATION_TYPE)
- public @interface Target {
- ElementType[] value();
- }
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
他接受一个ElementType数组作为参数.说明注释的使用范围可以是多个地点.
- @Target({ElementType.METHOD,ElementType.TYPE})
@Target({ElementType.METHOD,ElementType.TYPE})
我们把MyAnnotation的声明改为即可以使用在方法上也可以用于类.接口.枚举上
下面是ElementType的原码以及各种类所应用的范围;
- public enum ElementType {
- TYPE, // 适用 class, interface, enum
- FIELD, // 适用 field
- METHOD, // 适用 method
- PARAMETER, // 适用 method 上之 parameter
- CONSTRUCTOR, // 适用 constructor
- LOCAL_VARIABLE, // 适用区域变量
- ANNOTATION_TYPE, // 适用 annotation 型态
- PACKAGE // 适用 package
- }
public enum ElementType {
TYPE, // 适用 class, interface, enum
FIELD, // 适用 field
METHOD, // 适用 method
PARAMETER, // 适用 method 上之 parameter
CONSTRUCTOR, // 适用 constructor
LOCAL_VARIABLE, // 适用区域变量
ANNOTATION_TYPE, // 适用 annotation 型态
PACKAGE // 适用 package
}
- @Retention(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
标示MyAnnotation将被保存到什么时候RetentionPolicy.RUNTIME会告诉编译器.我这个注视要保存到CLASS文件中并且我会再运行时通过JAVA反射来使用他.
下面是RetentionPolicy的原码以及各种类所应用的范围;
- public enum RetentionPolicy {
- SOURCE, //编译器处理完Annotation信息后就没事了,也不会被保存在字节码中.
- CLASS, //编译器将Annotation储存于class档中.
- RUNTIME //编译器将Annotation储存于class檔中,可由JVM读入
- }
public enum RetentionPolicy {
SOURCE, //编译器处理完Annotation信息后就没事了,也不会被保存在字节码中.
CLASS, //编译器将Annotation储存于class档中.
RUNTIME //编译器将Annotation储存于class檔中,可由JVM读入
}
下面的代码演示了如何在运行时找到注释并得到数据.
- public class MyAnnotationDemo {
- //我想在这里标注作者信息
- @MyAnnotation(name = "JE") //如果不写参数默认是yh,这是default地作用
- public void getAnnotationDemo(){
- }
- public static void main(String[] args) {
- Class clazz = MyAnnotationDemo.class;
- Method[] methods = clazz.getMethods();
- for(Method m : methods) {
- if(m.isAnnotationPresent(MyAnnotation.class)){
- MyAnnotation ann = m.getAnnotation(MyAnnotation.class);
- System.out.println("MethodName = " + m.getName());
- System.out.println("name = " + ann.name());
- System.out.println("ann.age() = " + ann.age());
- }
- }
- }
- }
public class MyAnnotationDemo {
//我想在这里标注作者信息
@MyAnnotation(name = "JE") //如果不写参数默认是yh,这是default地作用
public void getAnnotationDemo(){
}
public static void main(String[] args) {
Class clazz = MyAnnotationDemo.class;
Method[] methods = clazz.getMethods();
for(Method m : methods) {
if(m.isAnnotationPresent(MyAnnotation.class)){
MyAnnotation ann = m.getAnnotation(MyAnnotation.class);
System.out.println("MethodName = " + m.getName());
System.out.println("name = " + ann.name());
System.out.println("ann.age() = " + ann.age());
}
}
}
}