Java注解的作用
1、生成文档。这是最常见的,也是java 最早提供的注解。常用的有@see @param @return 等
2、跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。以后java的程序开发,最多的也将实现注解配置,具有很大用处;
3、在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
其实注解也就是一个类文件
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具盒其他程序可以使用反射来了解你的类以及各种元素上有无某种标记,看你有什么标记,就去干相应的事。标记可以加在包、类、字段、方法、方法的参数以及局部变量上
看java.lang包,可以看到JDK中提供的最基本的Annotation
都是从jdk1.5以后开始的
public @interface Deprecated
用@Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface Override
表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
public @interface SuppressWarnings
指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。
根据风格不同,程序员应该始终在最里层的嵌套元素上使用此注释,在那里使用才有效。如果要在特定的方法中取消显示某个警告,则应该注释该方法而不是注释它的类。
自定义注解:在interface前面加上一个@
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/***
* Retention:保持、保留
* RetentionPolicy:政策、方针
*@Retention
*1、指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS
*2、有三种取值(代表三个阶段):
* RetentionPolicy.SOURCE:保留注解到java源文件阶段,例如Override、SuppressWarnings
* RetentionPolicy.CLASS:保留注解到class文件阶段,例如
* RetentionPolicy.RUNTIME:保留注解到运行时阶段即内存中的字节码,例如Deprecated
*/
//元注解:表示的是注解的注解,(同义词有元信息、元数据)
//如果不加,javac会把这无用的注解丢掉
@Retention(RetentionPolicy.RUNTIME)//这个注解一直要保留的运行阶段
@Target({ElementType.METHOD,ElementType.TYPE})//这个注解表示作用的位置,ElementType.METHOD表示只能把注解写到方法上,ElementType.TYPE表示可以写到类上、方法上、枚举上等
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}) //这个注解表示作用的位置,ElementType.METHOD表示只能把注解写到方法上,ElementType.TYPE表示可以写到类上、方法上、枚举上
public @interface MyAnnotation {
Stringcolor() default "blue";//方法,但是相当于注解的属性,即:当成属性赋值,当成方法调用
Stringvalue();
int []arrayAttr() default {1,2,3}; //返回值是数组对象
MetaAnnotationannotationAttr() default @MetaAnnotation("lxj"); //返回值是注解类型
Class<PersonChiness>classType() default PersonChiness.class; //返回CLASS对象
}
注解的使用实例
@MyAnnotation(color="green",value="3",arrayAttr={2,7,8}, annotationAttr=@MetaAnnotation("wangjingaa"))
//如果数据只有一个值可以写为
//@MyAnnotation(color="green",value="3", arrayAttr=1)
publicclassAnnotationDemo1 {
@SuppressWarnings("deprecation")//表示这个方法已经过时了,但是我知道,在编译时不要提醒我
@MyAnnotation(value ="xx" )
publicstaticvoid main(String[] args) {
System.runFinalizersOnExit(true);
//判断是否有这个注解
if(AnnotationDemo1.class.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation myAnnotation =AnnotationDemo1.class.getAnnotation(MyAnnotation.class);
System.out.println(myAnnotation.color());
System.out.println(myAnnotation.value());
System.out.println(myAnnotation.arrayAttr().length);
System.out.println(myAnnotation.annotationAttr().value());
System.out.println(myAnnotation.classType().newInstance().sayHello("hello,kitty"));
}
}
publicstaticvoid sayHello() {
System.out.println("hi,hello");
}
}
总结:
1. 数组类型的属性
1) Int[] arrayAttr() default{1,2,3};
2) @MyAnnotation(arrayAttr={2,3,4})
3) 如果数组属性中只有一个元素,这是属性值部分可以省略大括号
2. 枚举类型的属性
1) EnumTest.TrafficLamp lamp();
2) @MyAnnotation(lamp =EnumTest.TrafficLamp.GREEN)
3. 注解类型的属性
1) MetaAnnotationannotationAttr() default @MetaAnnotation(“xxx”);
2) @MyAnnotation(annotationAttr=@MetaAnnotation(“yyyy”));
3) 可以认为上面这个@MyAnnotation是MyAnnotation类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotation类的一个实例对象,调用一下代码:MetaAnnotation ma = myAnnotation.annotationAttr();
System.out.println(ma.value);
4. 注解的详细语法可以通过看java语法规范了解,即看java的languagespecification