注解的定义
注解(Annotation)很重要,未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是基于注解的了,注解是一种趋势,现在已经有不少的人开始用注解了,注解是JDK1.5之后才有的新特性。
JDK1.5之后内部提供的三个注解
@Deprecated 意思是“废弃的,过时的”
@Override 意思是“重写、覆盖”
@SuppressWarnings 意思是“压缩警告”
元注解
元注解是可以注解到注解上的注解 ,也就是一张标签, 有 @Retention、@Documented、@Target、@Inherited、@Repeatable 5 种。
Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。
它的取值如下:
- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
- RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
- RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
@Documented
顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去。
@Target
Target 是目标的意思,@Target 指定了注解运用的地方。
你可以这样理解,当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。
类比到标签,原本标签是你想张贴到哪个地方就到哪个地方,但是因为 @Target 的存在,它张贴的地方就非常具体了,比如只能张贴到方法上、类上、方法参数上等等。@Target 有下面的取值
- ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
- ElementType.CONSTRUCTOR 可以给构造方法进行注解
- ElementType.FIELD 可以给属性进行注解
- ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
- ElementType.METHOD 可以给方法进行注解
- ElementType.PACKAGE 可以给一个包进行注解
- ElementType.PARAMETER 可以给一个方法内的参数进行注解
- ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
@Inherited
Inherited 是继承的意思,但是它并不是说注解本身可以继承,而是说如果一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。 说的比较抽象。代码来解释。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}
@Test
public class A {}
public class B extends A {}
注解 Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解。
@Repeatable
Repeatable 自然是可重复的意思。@Repeatable 是 Java 1.8 才加进来的,所以算是一个新的特性。
什么样的注解会多次应用呢?通常是注解的值可以同时取多个。
为注解增加属性
注解:如果一个注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略掉“value=”部分; default 默认值。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface MyAnnotation {
String color() default "blue";
String value();
应用注解
@MyAnnotation("jacky")
public class AnnotationUse {
}
测试
public class MyAnnotationTest {
public static void main(String[] args) {
if (AnnotationUse.class.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation myAnnotation = (MyAnnotation) AnnotationUse.class.getAnnotation(MyAnnotation.class);
System.out.println(myAnnotation.color());
System.out.println(myAnnotation.value());
} else {
System.out.println("nothing");
}
}
为注解增加高级属性
枚举类
public enum EumTrafficLamp {
RED,//红
YELLOW,//黄
GREEN//绿
}
注解
public @interface MetaAnnotation {
String value();
}
注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface AdvancedAnnotation {
String color() default "blue";//为属性指定缺省值
String value();//定义一个名称为value的属性
//添加一个int类型数组的属性
int[] arrayAttr() default {1, 2, 4};
//添加一个枚举类型的属性,并指定枚举属性的缺省值,缺省值只能从枚举类EumTrafficLamp中定义的枚举对象中取出任意一个作为缺省值
EumTrafficLamp lamp() default EumTrafficLamp.RED;
//为注解添加一个注解类型的属性,并指定注解属性的缺省值
MetaAnnotation annotationAttr() default @MetaAnnotation("xdp");
}
注解应用类
@AdvancedAnnotation(color = "red",
value = "jacky",
arrayAttr = {3, 5, 6},
lamp = EumTrafficLamp.GREEN,
annotationAttr = @MetaAnnotation("cheung"))
public class AdvancedAnnotationUse {
}
测试类
public class AdvancedAnnotationUseTest {
public static void main(String[] args) {
if (AdvancedAnnotationUse.class.isAnnotationPresent(AdvancedAnnotation.class)) {
AdvancedAnnotation advancedAnnotation = (AdvancedAnnotation) AdvancedAnnotationUse.class.getAnnotation(AdvancedAnnotation.class);
System.out.println("color:"+advancedAnnotation.color()+",value:"+advancedAnnotation.value()+",arrLength:"+advancedAnnotation.arrayAttr().length+",lamp:"+advancedAnnotation.lamp()+",annotationValue:"+advancedAnnotation.annotationAttr().value());
}
}
}
文章转载自: