码迷,mamicode.com
首页 > 编程语言 > 详细

Java基础:注解Annotation

时间:2015-02-06 17:04:09      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:

从JDK5开始,Java增加了注解(Annotation),注解是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。通过使用注解,开发人员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充的信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证、处理或者进行部署。

注解提供了一种为程序元素(包、类、构造器、方法、成员变量、参数、局域变量)设置元数据的方法。跟public、static等修饰符一样,注解是这些程序元素的属性,是这些程序元素的一部分,不能脱离程序元素使用。

如果希望注解在运行时起到作用,需要访问和处理注解的工具,这些工具统称为APT(Annotation Processing Tool)。

1  基本注解

JDK默认提供了如下几个基本注解:

  • @Override 

限定重写父类方法。对于子类中被@Override 修饰的方法,如果存在对应的被重写的父类方法,则正确;如果不存在,则报错。@Override 只能作用于方法,不能作用于其他程序元素。

  • @Deprecated

用于表示某个程序元素(类、方法等)已过时。如果使用被@Deprecated修饰的类或方法等,编译器会发出警告。

  • @SuppressWarning

抑制编译器警告。指示被@SuppressWarning修饰的程序元素(以及该程序元素中的所有子元素,例如类以及该类中的方法.....)取消显示指定的编译器警告。例如,常见的@SuppressWarning(value="unchecked")

  • @SafeVarargs

@SafeVarargs是JDK 7 专门为抑制“堆污染”警告提供的。


2 元注解

为了修饰注解定义,JDK提供了如下4个元注解(注解的注解):

  • @Retention

  • @Target

  • @Documented

  • @Inherited

2.1 @Retention

@Retention修饰一个Annotation定义,用于指定被修饰的Annotation可以保留多长时间。

@Retention包含一个value成员变量,该value成员变量是RetentionPolicy枚举类型的。使用@Retention时,必须为其value指定值。

value成员变量的值只能是如下3个:

  • RetentionPolicy.SOURCE:注解只保留在源代码中,编译器编译时,直接丢弃这种注解。

  • RetentionPolicy.CLASS:编译器把注解记录在class文件中。当运行Java程序时,JVM中不再保留该注解。

  • RetentionPolicy.RUNTIME:编译器把注解记录在class文件中。当运行Java程序时,JVM会保留该注解,程序可以通过反射获取该注解的信息。

示例:

package com.demo1;

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

//@Retention(value=RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnTest {
	String name() default "sunchp";
}

如果注解里有一个value成员变量,使用该注解时可以直接在注解后的括号里指定value成员变量的值,无须使用name=value形式。

2.2 @Target

@Target修饰一个注解定义,用于指定被修饰的注解能用于修饰哪些程序元素。@Target也包含一个名为value的成员变量,该成员变量的值有如下几个:

  • ElementType.TYPE:能修饰类、接口或枚举类型

  • ElementType.FIELD:能修饰成员变量

  • ElementType.METHOD:能修饰方法

  • ElementType.PARAMETER:能修饰参数

  • ElementType.CONSTRUCTOR:能修饰构造器

  • ElementType.LOCAL_VARIABLE:能修饰局部变量

  • ElementType.ANNOTATION_TYPE:能修饰注解

  • ElementType.PACKAGE:能修饰包

示例1(单个ElementType):

package com.demo1;

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

@Target(ElementType.FIELD)
public @interface AnnTest {
	String name() default "sunchp";
}

示例2(多个ElementType):

package com.demo1;

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

@Target({ ElementType.FIELD, ElementType.METHOD })
public @interface AnnTest {
	String name() default "sunchp";
}

2.3 @Documented

@Documented用于指定被该元注解修饰的注解类定义,将被javadoc工具提取成文档。如果定义注解类A时,使用了@Documented,则所有使用该注解类A修饰的程序元素的API文档中,将会包含该注解类A的说明。

示例:

@Documented
public @interface Testable {
}
public class Test {
	@Testable
	public void info() {
	}
}

技术分享

2.4 @Inherited

@Inherited指定被它修饰的注解具有继承性。

示例:

package com.demo2;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Inheritedable {

}
package com.demo2;

@Inheritedable
public class Base {

}
package com.demo2;

//SubClass只是继承了Base类
//并未直接使用@Inheritedable注解修饰
public class SubClass extends Base {
	public static void main(String[] args) {
		System.out.println(SubClass.class.isAnnotationPresent(Inheritedable.class));
	}
}

如果Inheritedable 注解被@Inherited修饰,则运行结果为:true;如果Inheritedable 注解没有被@Inherited修饰,则运行结果为:false。


3 自定义注解



4 注解与反射



5 注解本质



6 注解的意义



Java基础:注解Annotation

标签:

原文地址:http://my.oschina.net/sunchp/blog/376120

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!