概念
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。在java.lang包中,可看到JDK中提供的最基本的annotation。
常见注解
1、过时:@Deprecated
@Deprecated
public static void sayHello() {
System.out.println("nihao");
}
2、警告::@SuppressWarnings("deprecation")
@SuppressWarnings("deprecation")
public static void main(String[] args) {
System.runFinalizersOnExit(true);
}
3、重写:@Override
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
注解的应用
书写格式
首先我们写一个注解类
@interface A
{
}
注解应用结构图
首先我们写一个注解类
@Retention(RetentionPolicy.RUNTIME)
public @interface ItcastAnnotation {
}
注意:这里的@Retention(RetentionPolicy.RUNTIME)是注解的注解(元注解),表示注解的声明周期
RetetionPolicy.SOURCE、RetetionPolicy.CLASS、RetetionPolicy.RUNTIME;
分别对应:java源文件-->class文件-->内存中的字节码。
分别对应:java源文件-->class文件-->内存中的字节码。
在其他类中使用该注解
@ItcastAnnotation
public class AnnotationTest {
public static void main(String[] args) {
//通过当前类的字节码文件检查注解ItcastAnnotation是否在当前类上
if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){
//得到注解ItcastAnnotation
ItcastAnnotation annotation=(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
System.out.println(annotation);
}
}
}
注意:如果上一步骤没有指定RetentionPolicy.RUNTIME这时将打印不出,因为我们无法从内存中加载该注解的文件对象
指定注解可以使用的位置,在注解类的上面加上
@Target({ ElementType.TYPE, ElementType.METHOD })// 指定注解可放在类或者方法上
Target的默认值为任何元素,设置Target等于ElementType.METHOD,原来加在类上的注解就报错了,改为用数组方式设置{ElementType.METHOD,ElementType.TYPE}就可以了。
为注解增加属性
什么是注解的属性?
一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是传智播客的学生,否则,就不是。如果还想区分出是传智播客哪个班的学生,这时候可以为胸牌在增加一个属性来进行区分。
书写规则
注解的属性书写类似于方法的书写,如:
String color();
如果要指定默认值需要用defallt
String color() default "blue";
在类中怎么使用
@ItcastAnnotation(color="red")
我们可以通过得到的注解打印出color
System.out.println(annotation.color());
注意:有一个属性比较特殊就是value,如果属性名是value并且其他属性都有默认值,并且只有value属性需要赋值,在使用value的时候可以不用写value=“xxx”,可以直接写“xxx”,
如:在注解类中加上
String value(); 在测试类中写上
@ItcastAnnotation("xyz")
另外,如果注解类中的属性没有设置默认值,则在测试类中必需指定默认值,如果在注解类中已经有默认值,则在测试类中可以不写该属性
数组属性
int [] nums() default {3,4,4};
测试类中书写
@ItcastAnnotation(nums={2,3,4})
如果设置数组只有一个元素可以不用写{ },写成@ItcastAnnotation(nums=2)
System.out.println(annotation.nums().length);
枚举属性
EnumDemo.Days days() default EnumDemo.Days.MON;
测试类中书写
@ItcastAnnotation(days=EnumDemo.Days.SUN)
System.out.println(annotation.days().nextDay());
注解属性
MetaAnnotation ma()default @MetaAnnotation("ma");此处可以省略value="ma"
测试类中书写
@ItcastAnnotation(ma=@MetaAnnotation("hello"))
System.out.println(annotation.ma().value());
代码示例
注解类ItcastAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })// 指定注解可放在类或者方法上
public @interface ItcastAnnotation {
String color() default "blue";
int [] nums() default {3,4,4};
String value();
EnumDemo.Days days() default EnumDemo.Days.MON;
EnumDemo.TrafficLamp lamp() default EnumDemo.TrafficLamp.RED;
MetaAnnotation ma()default @MetaAnnotation("ma");
}
作为属性的注解类MetaAnnotation
public @interface MetaAnnotation {
String value();
}
测试类AnnotationTest
@ItcastAnnotation(ma=@MetaAnnotation("hello"),color="red",value="abc",nums={2,3,4},lamp=TrafficLamp.GREEN,days=EnumDemo.Days.SUN)
public class AnnotationTest {
@SuppressWarnings("deprecation")
@ItcastAnnotation("xyz")//只有注解中其他元素都有缺省值 即默认值的时候 才能省略value=
public static void main(String[] args) {
System.runFinalizersOnExit(true);
// sayHello();
//通过当前类的字节码文件检查注解ItcastAnnotation是否在当前类上
if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){
//得到注解ItcastAnnotation
ItcastAnnotation annotation=(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
System.out.println(annotation);
System.out.println(annotation.color());
System.out.println(annotation.value());
System.out.println(annotation.nums().length);
System.out.println(annotation.days().nextDay());
System.out.println(annotation.lamp().nextLamp());
System.out.println(annotation.ma().value());
}
}
}