java注解总结

来源:互联网 发布:python bytes函数 编辑:程序博客网 时间:2024/05/18 19:22

一、什么是注解

在jdk5.0之后的版本,java引入了注解。注解让程序员可以直接编写元数据,元数据即描述数据的数据,换句话说,注解是代码的元数据,它修饰、并描述了java代码,包括包、类、方法、变量、参数等。

二、注解的作用

1、生成文档。这是最常见的,也是Java 最早提供的注解。常用的有@see@param @return 等。

2、跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。以后java的程序开发,最多的也将实现注解配置,具有很大用处。

3、在编译时进行格式检查。如@override放在方法前,如果你这个方法并不是覆盖了父类方法,则编译时就能检查出。

4、代码生成。注解可以使用代码中展现的元数据信息来自动生成代码或者XML文件,一个不错的例子是JAXB。

三、注解分类


3.1 Java自带的普通注解

@Override 表明当前方法是覆盖了父类方法
abstract class Fruit{    protected void showOnTheDesk(){        ...    }}class Apple implements Fruit{    @Override    public void showInTheDesk(){ //编译报错,父类是On不是In        ...    }  }

@Deprecated:说明被标记的元素不推荐使用。这个注解会让编译器产生警告消息。可以使用到方法,类和域上。

@Deprecatedpublic void badMethod(){ //已经不推荐使用的方法...}

@SuppressWarnings 关闭不当的编译器警告信息。
@SuppressWarnings("unused")private String myNotUsedMethod(){ // 因为该私有方法未使用编译器产生了告警信息,使用@SuppressWarnings关闭警告 ...}

3.2 元注解

注解的注解,即是元注解。

普通注解来修饰java代码,而元注解用来修饰普通注解,换句话说,可以用元注解来自定义注解。

Java提供的最主要的元注解有4个:@Retention  @Target  @Documented  @Inherited

3.2.1 @Documented

@Documented修饰的注解会自动生成到javadoc中
@Documented@interface Column {  int  id() default -1;}

3.2.2 @Inherited

@Inherited修饰的注解类似于继承一样,但并非真的继承,只可以让子类对象使用反射中的getAnnotations()接口获取父类被@Inherited修饰的注解。

@Inherited@Retention(RetentionPolicy.RUNTIME)public @interface WithInherAnno {}@Retention(RetentionPolicy.RUNTIME)@interface NoInherAnno {}@WithInherAnnopublic static class Father1 {}public static class Son1 extends Father1 {}@ NoInherAnnopublic static class Father2 {}public static class Son2 extends Father2 {}public static void main(String[] args) {System.out.println(Arrays.toString(new Son1().getClass().getAnnotations()));System.out.println(Arrays.toString(new Son2().getClass().getAnnotations()));}

输出:

[@WithInherAnno()]

[]


3.2.3 @Retention

@Retention定义了注解的生命周期,即该注解被保留时间的长短。

某些注解仅出现在源码中,被编译器丢弃;

某些注解被编译在class文件中,加载到JVM中被忽略;

还有的注解被加载到JVM中,在Runtime期间可用(请注意并不影响class的执行,因为Annotation与class在使用上是分离的)。


@Retention的原始定义如下:

public @interface Retention{    RetentionPolicy value();}

@Retention的取值是RetentionPolicy类型,包括如下3种情况:

(1)SOURCE: 注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃。

(2)CLASS: 注解被保留到class文件,jvm加载class文件时候被遗弃。

(3)RUNTIME: 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在,保存到class对象中,可以通过反射来获取。

@Retention(RetentionPolicy.RUNTIME)public @interface SelfAnno {}

3.2.4 @Target

@Target定义了该注解要修饰的目标,即该注解所修饰的代码范围。

注解可被用来修饰 package、类、接口、enum、注解类型、方法、构造函数、成员变量、函数参数和局部变量(如循环变量、catch参数)等。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。


@Target原始定义如下:

public @interface Target{    ElementType[] value();}

@Target取值是ElementType[]数组,可取如下值:

(1)TYPE:指的是在类,接口(包括注解)或者enum上使用的注解。
(2)FIELD:指的在field属性,也包括enum常量使用的注解。
(3)METHOD:指的是在方法声明上使用的注解。
(4)PARAMETER:指的是在参数上使用的注解,
(5)CONSTRUCTOR: 指的是在构造器使用的注解。
(6)LOCAL_VARIABLE:指的是在局部变量上使用的注解。
(7)ANNOTATION_TYPE:指的是在注解上使用的元注解
(8)PACKAGE:指的是在包上使用的注解。


3.3 自定义注解

1)使用@interface来声明一个注解。

2)自定义的注解,自动继承自java.lang.annotation.Annotation接口,不能继承其他的接口。

3)注解包含注解参数,每一个注解参数在自定义注解时以方法的形式来声明,方法名就是参数名,返回值类型就是参数的类型(只能是基本类型、Class、String、enum)。

4)可使用default关键字来声明注解参数的默认值。

5)若自定义的注解只包含一个参数,建议把参数名设为”value”。

6)使用注解修饰代码时,其参数赋值通过@AnnoName(arg1=value1, arg2=value2…)的形式。

自定义注解的格式如下:

@interface 注解名{注解参数1声明;注解参数2声明;……}

下面以@Target源码为例:

@Retention(value = RetentionPolicy.RUNTIME)@Target(value = { ElementType.ANNOTATION_TYPE } )public @interface Target{    ElementType[] value();}

分析如下:

1、用@Retention修饰,其参数value的值为RetentionPolicy.RUNTIME。

2、用@Target修饰,其参数value是个数组,用{}形式赋值,值为ElementType.ANNOTATION_TYPE。

3、定义的Target注解,其注解参数名为value,类型为ElementType[]。

注:若注解的参数名是value,在使用该注解修饰代码时可以简写。如果参数类型为数组,但是只赋值一个元素,也可以简写。如上面的简写形式为:
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)

注解参数带默认值的自定义注解举例如下:

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface PeopleAge {    int value() default 0;}

四、Java注解的图例小结



五、使用注解的类库

Junit

这个框架用于完成Java中的单元测试。自JUnit4开始,注解被广泛应用,成为Junit设计的主干之一。

基本上,JUnit处理程序通过反射读取类和测试套件,按照在方法上,类上的注解顺序地执行它们。当然还有一些用来修改测试执行的注解。其它注解都用来执行测试,阻止执行,改变执行顺序等等。

@Test:这个注解向JUnit说明这个被注解的方法是一个可执行的测试方法。这个注解只能修饰方法,并且被JVM保留至运行时。

@Testpublic void test(){}

@Before:这个注解用来向JUnit说明被修饰的方法应该在所有测试方法之前被执行,常用于测试执行之前初始化,同样只修饰方法。

@ Beforepublic void init(){}

@After:这个注解用来向JUnit说明被注解的方法应该在所有单元测试之后执行,通常用来释放资源,或做一些清理、重置工作。

@Afterpublic void destroy(){}


Hibernate ORM

Hibernate是一个使用广泛的对象关系模型(ORM)映射类库,它提供了对象模型和关系型数据库的映射框架,使用注解作为设计的一部分。

@Entity@Table( name = "hibernate_annotated" )public class HibernateAnnotated{@Id@GeneratedValue@Column( name = "id" )private int id;@Column( name = "description" )private String description;}

上述代码将被注解的”HibernateAnnotated”类与数据库中的表”hibernate_annotated”映射对应,且主键为”id”,还有一列” description”。


Spring

Spring是使用广泛的Java企业级应用框架,其一项重要的特性就是在Java程序使用依赖注入。

Spring使用注解作为XML的一种替代方式,可用注解来配置项目。

@Componentpublic class DependencyInjectionAnnotation{  private String description;  public String getDescription() { return description; }  @Autowired public void setDescription( String description ) { this.description = description; }}

@Component:表示被修饰的类,将被Spring容器实例化并管理。

@Autowired:Spring容器将会尝试通过类型(这是一种元素匹配机制)使用这个set方法来自动装配。


JAXB

JAXB是一个用来相互转换和映射XML文件与Java对象的类库,这个类库与标准JRE一起提供,可直接引入java.xml.bind.annotation 包下的类直接使用。

@XmlType( propOrder = { "brand", "model", "year", "km" } )@XmlRootElement( name = "Car" )class Car {……}

上述声明一个类应该是XML文件中的一个节点,@XmlType、@XmlRoootElement用来告知 JAXB 处理程序,这个Car类在转换后,将会成为XML中的一个节点。@XmlType说明了属性在XML中的顺序。JAXB将会基于这些注解执行合适的操作。


参考文章:

http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html

http://blog.csdn.net/duo2005duo/article/details/50505884

http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html

http://www.importnew.com/14227.html

http://blog.csdn.net/beyond0851/article/details/8520993

http://swiftlet.net/archives/1906

原创粉丝点击