详细的解答下你的疑问:还有不明白的话个别再问啊。
JDK5新特性-Annotation注解
1.Annotation:新版的ejb,Spring,hibernate,struts2有一部分也是基于注解的
2.3个JDK自带的注解:
(1)@SuppressWarnings注解:
public class AnnotationTest {
public static void main(String[] args) {
System.runFinalizersOnExit(true);
}
}
用eclipse会发现中间加了一道线,意思是过时了,
用javac发现:使用或覆盖了已过时的 API这个警告
但是,当我们在main方法前边加上@SuppressWarnings("deprecation")的时候,再编译,就不再输出警告信息了。@SuppressWarnings("deprecation")这就是一个注解,用于告诉javac编译器该怎样。
一个注解就是一个类。
(2)@Deprecated注解:
假设我们的类中有一个类的一个方法:
public static void sayHello(){
System.out.println("itcast");
}
我们现在想让这个类作废,该怎么做呢?
可以加上一个注解:@Deprecated,这就说明这个方法已经作废。那么别人在引用的时候就会提示方法已经过时。
(3)@Override:覆盖父类的方法
假如我们想覆盖类的equals方法:
public boolean equals(Point pt){
}
但是实际上这个方法并不是重写的Object的equals,如何限定我们就是覆盖的Object的equals而不会出错呢?当我们在方法前面加上@Override注解的时候,编译时就会提示我们其实并没有覆盖!
总结一下:注解就是一个标记,加了注解就相当于给程序打了一种标记。
标记可以加载包上,类上,方法上,成员变量,方法的参数,方法的局部变量上面。
3.如何应用注解?
应用注解就相当于调用一个特殊的类,首先得有这么一个注解类。
注解类:
@interface A{
}
应用了“注解类”的类
@A
Class B{
}
对应用了注解类的类进行反射操作的类。
Class C{
B.class.isAnnotationPresent(A.class);
A a=B.class.getAnnotion(A.class);
}
下面我们做一个例子:
public @interface ItCastAnnotation{}
@ItCastAnnotation
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
if(AnnotationTest.class.isAnnotationPresent(ItCastAnnotation.class)){
ItCastAnnotation annotation=(ItCastAnnotation)
AnnotationTest.class.getAnnotation(ItCastAnnotation.class);
System.out.println(annotation);
}else System.out.println(false);
}
}
竟然输出是false,为什么呢?
原来需要这样修改注解类:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface ItCastAnnotation{
}
为我们的注解类添加注解,这叫注解的注解,就是元注解。
然后再来运行,输出结果:@edu.sdkd.ItCastAnnotation()
@Retention(RetentionPolicy.RUNTIME)这个注解的意思就是:要让注解一直保留到运行时。
当javac把源文件编译成class的时候,需要做一些处理,而当jvm用类加载器把class里面的二进制数据加载进内存的时候,也要做一些处理,然后生成字节码Class。
因此,一个注解的生命周期有三个阶段:源文件->class文件->字节码。在设计注解的时候就需要指定
注解存在的生命周期,用@Retention来指定,默认是保留在class阶段。
Override的Retention是保留在source阶段,SuppressWarnings也是给编译器看的,保留在sourfce阶段,Deprecated是保留在运行时Runtime。
Retention的取值是一个enum,这个enum的名字叫做:RetentionPolicy,有三个常量和两个方法,CLASS,RUNTIME,SOURCE和static RetentionPolicy valueOf(String name) ,static
RetentionPolicy[] values() 。
下面再加一个注解:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItCastAnnotation{
}
@Target意思是说作用的对象,是类还是方法等等,target的取值也是一个枚举ElementType,它里面有很多字段:ANNOTATION_TYPE,CONSTRUCTOR ,FIELD ,LOCAL_VARIABLE ,METHOD,PACKAGE ,PARAMETER,TYPE(包括Class, interface (包括注解), or enum declaration)。
4.如何为注解增加属性?
<font color="red">color就是属性
public @interface ItCastAnnotation{
String color();
}
注解有一个方法,返回一个字符串,也就是说这个注解有一个属性,他的名字就叫方法的名字color。那么在创建这个注解的时候,就需要给这个属性进行赋值。
@ItCastAnnotation(color="red")
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
if(AnnotationTest.class.isAnnotationPresent(ItCastAnnotation.class)){
ItCastAnnotation annotation=(ItCastAnnotation)
AnnotationTest.class.getAnnotation(ItCastAnnotation.class);
System.out.println(annotation.color());//输出red
}else System.out.println(false);
}
}
有一个特殊的属性:value
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItCastAnnotation{
String color();
String value();
}
@ItCastAnnotation(color="red",value="abs")
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
if(AnnotationTest.class.isAnnotationPresent(ItCastAnnotation.class)){
ItCastAnnotation annotation=(ItCastAnnotation)
AnnotationTest.class.getAnnotation(ItCastAnnotation.class);
System.out.println(annotation.color()+","+annotation.value());
}else System.out.println(false);
}
}
如果注解只有value属性,那么就可以不写value。
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItCastAnnotation{
String color() default "red";//给属性提供一个默认值
String value();
}
@ItCastAnnotation("abs")
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
if(AnnotationTest.class.isAnnotationPresent(ItCastAnnotation.class)){
ItCastAnnotation annotation=(ItCastAnnotation)
AnnotationTest.class.getAnnotation(ItCastAnnotation.class);
System.out.println(annotation.color()+","+annotation.value());
}else System.out.println(false);
}
}
从@Retention(RetentionPolicy.RUNTIME)我们可以知道:有一个属性是value,它的返回值类型是一个枚举RetentionPolicy。
5.为注解增加更复杂的类型
(1)增加数组属性:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItCastAnnotation{
String color() default "red";
String value();
int[] intArr();
}
@ItCastAnnotation(value="abs",intArr={1,2,3})
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
if(AnnotationTest.class.isAnnotationPresent(ItCastAnnotation.class)){
ItCastAnnotation annotation=(ItCastAnnotation)
AnnotationTest.class.getAnnotation(ItCastAnnotation.class);
System.out.println(java.util.Arrays.toString(annotation.intArr()));
}else System.out.println(false);
}
}
输出1,2,3
如果数组里面只有一个元素,就可以不用{}也可以。
(2)假如属性是枚举类型:
public @interface ItCastAnnotation{
String color() default "red";
String value();
int[] intArr() default {3,4,5};
Lamp lamp() default Lamp.RED;
}
public enum Lamp {
RED,GREEn,YELLOW;
}
System.out.println(annotation.lamp());
(3)假如属性是注解类型:
新建一个注解:
public @interface MetaAnnotation {
String value();
}
增加一个注解属性:
public @interface ItCastAnnotation{
String color() default "red";
String value();
int[] intArr() default {3,4,5};
Lamp lamp() default Lamp.RED;
MetaAnnotation annotationAttr() default @MetaAnnotation("hello");
}
主调函数:
@ItCastAnnotation(value="abc",color="red",annotationAttr=@MetaAnnotation("world"))
System.out.println(annotation.annotationAttr());
|