Java Annotations详解

       Java注释被用来为java代码提供元数据(meta data)。作为元数据,注释不会直接影响代码的执行结果,不过事实上有些注释就是为了影响代码的执行结果而定义的。

      Java注释是从Java 5开始添加的。本文对于Java注释的讨论是基于java 6的,据我所知,到目前为止Java 7中关于注释的部分并没有发生改变,所以本文对java 7编程人员上来说应该也是可用的。

      目录:

      · Java 注释的作用

     · 注释的基础知识

     · 注释的位置

     · Java中预置的注释

     · 创建你自己的注释

Java 注释的作用

     预编译指令(Compiler instructions)

    编译时指令(Build-time instructions)

    运行时指令(Runtime instructions)

    Java有三个编译注释,你可以使用它们来给编译器发送指令。这些注释会在稍后再做更详细的介绍。

    Java注释可以在编译时(build-time)时使用,当你编译你的工程时。编译过程包括生成源代码,编译资源文件,生成XML文件(如:部署表述文件),以及将编译好的代码或文件打包成一个jar文件等。编译过程通常是由诸如Apache Ant或Apache Maven之类的编译工具自动完成的。编译工具会浏览你代码中的特定注释,并基于这些注释生成源代码或其他文件。

    通常情况下,Java注释在代码编译完成后就变得不可见了。但是存在这种可能,你可以定义自己的注释,并使它们在运行时仍然可见。之后可以通过反射机制来访问这些注释来影响你的程序。

注释的基本知识

    注释的最简单形式如下:

@Entity
     字符@告诉编译器这是一个注释,后面的Entity表示该注释的名称。

注释的元素
     一个注释可以包含多个可以被赋值的元素。一个元素就像是一个属性或者参数。下面是一个包含一个元素的注释

@Entity(tableName = "vehicles")
     元素紧跟在注释之后,并放置在圆括号中,没有元素的注释,不需要圆括号。注释可以包含多个元素,当只包含一个元素时,可以省略元素名,只提供元素值既可,如下:
@InsertNew("yes")

注释的位置

    你可以将注释放置到类、接口、方法、方法参数、成员变量、局部变量之前。下面是一个将注释放到类之前的例子:

@Entity
public class Vehicle {
}
    下面是一个更大的例子,演示了在类、成员变量、方法、参数以及局部变量之前添加注释。仅作演示之用,并没有什么特别的用意。
@Entity
public class Vehicle {

    @Persistent
    protected String vehicleName = null;


    @Getter
    public String getVehicleName() {
        return this.vehicleName;
    }

    public void setVehicleName(@Optional vehicleName) {
        this.vehicleName = vehicleName;
    }

    public List addVehicleNameToList(List names) {

        @Optional
        List localNames = names;

        if(localNames == null) {
            localNames = new ArrayList();
        }
        localNames.add(getVehicleName());

        return localNames;
    }

}

Java预置的编译注释

    Java支持三个可以用来给编译相关的注释,它们是:

    · @Deprecated

    · @Override

    · @SuppressWarings

    下面将对它们此次做解释

@Deprecated

    @Deprecated用来标记一个类、方法、成员变量已经被舍弃了。如果你的代码中使用舍弃(Deprecated)的类、方法或成员变量,那么编译器会给你一个警告。下面是一个例子:

@Deprecated
public class MyComponent {

}
    当你使用@Deprecated表示舍弃时,你也可以在Java文档中对舍弃的原因加以说明。

@Override

    @Override被用在方法前,用来说明覆盖了父类中的方法。假如一个方法被@Override修饰,但实际上它并没有覆盖任何方法,则编译器会提示一个错误。

    @Override并不是必须的,即覆盖父类方法时,也可以不在子类方法前面添加@Override。但是还是推荐使用@Override,因为这样做是有好处的,至少可以较少一些不必要的错误。如覆盖方法的方法名不对,并没有实现覆盖;或者有人修改了父类中的方法名,导致的子类中的覆盖失效,如果有@Override,编译器就会自动提示错误,从而避免了错误。

@SuppressWarnings

    使用@SuppressWarnings能够是编译器对指定的方法放弃提示警告。如方法中引用了已经被舍弃(@Deprecated修饰)的方法时。

创建你自己的注释

    创建自己的注释是有可能的。注释被定义在它们自己的文件中,就像Java中的类或接口一样。下面是一个例子:

@interface MyAnnotation {

    String   value();

    String   name();
    int      age();
    String[] newNames();

}
     这个例子定义了一个包含四个元素的叫MyAnnotation的注释。

     注意,每个元素的定义都很像接口中的方法定义。你可以使用原始数据类型定义元素的数据类型,你也可以使用数组定义元素的数据类型。但是不能使用复合对象(Complex Object定义元素的数据类型。

    要使用上面自定义的注释,可以这样做:

@MyAnnotation(
    value="123",
    name="Jakob",
    age=37,
    newNames={"Jenkov", "Peterson"}
)
public class MyClass {


}

元素的默认值

    你可以为一个元素指定默认值(有点像C++中的方法哈)。这样在注释初始化时那个元素就可以忽略了。如下定义了一个包含默认值的注释

@interface MyAnnotation {

    String   value() default "";

    String   name();
    int      age();
    String[] newNames();

}
    在调用时,可以忽略包含默认值的元素,这里指的是value元素,如:
@MyAnnotation(
    name="Jakob",
    age=37,
    newNames={"Jenkov", "Peterson"}
)
public class MyClass {


}

@Retention

    你可以指定你自定义的注释在运行时可用,通过反射检测。要实现这样的效果,你需要用@Retention修饰你自定义的注释,如下:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)

@interface MyAnnotation {

    String   value() default "";

}
    这里的@Retention(RetentionPolicy.RUNTIME)会告诉编译器和JVM当前这个注释是可以在运行时通过反射机制访问的。

     RetentionPolicy还包含了其他两个值:

         RetentionPolicy.CLASS:意味着该注释需要被保存在.class文件中,但是在运行时是不可用的。这是retention默认的值。

         RetentionPolicy.SOURCE:意味着该注释只在源代码中可用,而不是在.class文件,也不是在运行时。

@Target
    你可以指定那些Java元素(类、方法等)可以使用你自定义的注释。可以在定义你的Annotaion添加@Target来实现。如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
public @interface MyAnnotation {

    String   value();
}
    上面的代码限制了该注释只能用来注释方法(而不是类、成员变量之类的)

     ElementType.ANNOTATION_TYPE

     ElementType.CONSTRUCTOR

     ElementType.FIELD

     ElementType.LOCAL_VARIABLE

     ElementType.METHOD

     ElementType.PACKAGE

     ElementType.PARAMETER

    ElementType.TYPE

    上面大多数数值都是可以见文知意的,其中ANNOTATION_TYPE表示只能用来注释注释类型(Annotation),就像@Target和@Retention一样。

@Inherited

    @Inherited表明,一个子类实现了继承了父类中的注释,如下:

java.lang.annotation.Inherited

@Inherited
public @interface MyAnnotation {

}

@MyAnnotation
public class MySuperClass { ... }
public class MySubClass extends MySuperClass { ... }

    在这个例子中,MySubClass继承了父类MySuperClass中的@MyAnnotation注释。

@Documented

    @Documented用来表明你自定义的注释需要在JavaDoc中可见。如下:

java.lang.annotation.Documented

@Documented
public @interface MyAnnotation {

}
@MyAnnotation
public class MySuperClass { ... }

    当你生成MySupperClass类的JavaDoc文档时,@MyAnnotation注释会出现在JavaDoc文档中。

    这次不是"O啦~~~",而是

    哇偶~~~,终于结束了!!!

    转帖请保留出处:http://blog.csdn.net/u011638883/article/details/13168799

    谢谢!!



你可能感兴趣的:(java,annotation,详解)