了解注解及java提供的几个基本注解
如果某些方法已经过时了,但是你仍然想使用它,又不想编译器提出警告可以使用@SuppressWarnings("deprecation")
如果你想告诉别人某个方法已经过时了,想让后人减少对该方法的使用可以用@Deprecated
当你要对某个方法进行重写时,你想不出差错,应该使用@Override
总结:
注解相当于一种标记,加了注解就等于打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。
看java.lang包,可以看到JDK中提供的最基本得annotation。
注解的应用结构
1. 注解类
@interface A{}
2. 应用了注解类的类
@A
Class B{}
3. 对“应用了注解类的类”进行反射操作的类
Class C
{
B.class.isAnnotionPresent(A.class);
A a = B.class.getAnnotion(A.class);
}
下面的代码展示了最简单得这种结构:
public @interface ItcastAnnotation { }
------------------------------------------------------
@ItcastAnnotation
public class AnnotationTest {
public static void main(String[] args) throws Exception{
//判断当前类里面有没有ItcastAnnotation这个注解
if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){
//得到注解类
ItcastAnnotation annotation =
(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
System.out.println(annotation);
}
}
}
如果就这样打印在控制台,将看不到任何结果,因为jvm在加载类文件进入内存时,会去掉注解信息,此时你得指定注解要保留到什么时候
这个时候就要用到@Retetnion元注解,它有三种取值:
- 这个就是注解的生命周期Enum RetentionPolicy
- RetentionPolicy.SOURCE------>java源文件
- RetentionPolicy.CLASS------->class文件
- RetentionPolicy.RUNTIME---->内存中的字节码
那么在我们的注解类前面再加上这个注解就行了(注解的注解--元注解)
@Retention(RetentionPolicy.RUNTIME)//一直保留在运行期间
public @interface ItcastAnnotation { }
@Override ------>RetentionPolicy.SOURCE
@SuppressWarnings----->RetentionPolicy.SOURCE
@Deprecated---->RetentionPolicy.RUNTIME
注解加在类的什么位置可以用@Target元注解
Target的默认值为任何元素,设置Target等于ElementType.METHOD原来加在类上面的注解就报错了,改为用数组方式设置{ElementType.METHOD,ElementType.TYPE}就可以了。
可以为注解增加基本属性
定义基本类型的属性和应用属性
在注解类中增加String color()
@MyAnnotation(color ="red")
用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法
MyAnonotation a = (MyAnnotation)AnnotationTest.calss.getAnnotation(MyAnonotation.class)
System.out.println(a.color())
可以认为上面这个@MyAnnotation是MyAnnotation类的一个实例对象
为属性指定缺省值
String color()default "yellow";
value属性:
String value() default "zxx";
如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略value=部分,例如@MyAnnotation("lhm")
为注解增加高级属性
数组类型的属性
int[] arrayArr() default {1,2,3};
@MyAnnotation(arrayAttr={2,3,4})
如果数组属性中只有一个元素,这时候属性值部分可以省略大括号
枚举类型的属性
EnumTest.TrafficLamp lamp();
@MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN)
注解类型的属性
MetaAnnotation annotationAttr() default @MetaAnnotation("xxx");
@MyAnnotation(annotationAttr= @MetaAnnotation("yyy"))
可以认为上面这个@MyAnnotation是MyAnnotation类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotation类的一个实例对象,调用代码如下:
MetaAnnotation ma = myAnnotation.anntationAttr();
System.out.println(ma.value());
注解的详细语法可以通过看java语言规范了解,即看java的language specification。
注解的代码如下:
public @interface MetaAnnotation {
String value();
}
--------------------------------------------------------
@Retention(RetentionPolicy.RUNTIME)//一直保留在运行期间
@Target({ElementType.METHOD,ElementType.TYPE})
//指明可以添加到类前面和方法的前面
public @interface ItcastAnnotation {
String color() default "blue";
String value();
//数组类型
int[] arrayAttr() default {3,4,4};
//枚举类型的
EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;
//注解类型的属性
MetaAnnotation annotationAttr() default @MetaAnnotation("lhm");
}
---------------------------------------------------------------------------------
@ItcastAnnotation(annotationAttr=@MetaAnnotation("flx"),color="red",value="abc",arrayAttr=1)
//对于数组arrayAttr 可以这样赋值arrayAttr={1,2,3},如果数组中只有一个元素arrayAttr={1},也可以写成arrayAttr=1
public class AnnotationTest {
/**
* @param args
*/
@SuppressWarnings("deprecation")//不提示过时
@ItcastAnnotation("xyz")
public static void main(String[] args) throws Exception{
//判断当前类里面有没有ItcastAnnotation这个注解
if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){
//得到注解类
ItcastAnnotation annotation =
(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
System.out.println(annotation.color());
System.out.println(annotation.value());
System.out.println(annotation.arrayAttr().length);
System.out.println(annotation.lamp().nextLamp().name());
System.out.println(annotation.annotationAttr().value());
}