了解注解及java提供的几个基本注解(JDK1.5的新特性)了解和入门注解的应用·先通过@SuppressWarnings的应用让大家直观地了解注解:--RetentionPolicy.SOURCE -通过System.runFinalizersOnExit(true);的编译警告引出@SuppressWarnings("deprecation")当使用类过时的方法的时候,为类消除编译的时候编译器的提示,加上以上的注释,则再编译的时候javac就不会再提示警告了。下面是在doc窗口运行的示例:C:/Users/lqq/Workspaces/MyEclipse 8.6/javaenhance/src/lqq/heima/day2>javac AnnotationTest.java
C:/Users/lqq/Workspaces/MyEclipse 8.6/javaenhance/src/lqq/heima/day2>javac AnnotationTest.java注意:AnnotationTest.java 使用或覆盖了已过时的 API。注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。
C:/Users/lqq/Workspaces/MyEclipse 8.6/javaenhance/src/lqq/heima/day2>javac -Xlint:deprecation AnnotationTest.javaAnnotationTest.java:11: 警告:[deprecation] java.lang.System 中的 runFinalizersOnExit(boolean) 已过时 System.runSOURCEersOnExit(true); ^1 警告
·@Deprecated --RetentionPolicy.RUNTIME -直接在刚才的类中增加一个方法,并加上@Deprecated标注,在另外一个类中调用这个方法。 注解该方法已经过时。 @Deprecated public static void sayHello(){ System.out.println("hello,heima!"); }·@Override --RetentionPolicy.SOURCE -public boolean equals(Reflect other)方法与HashSet结合讲解·总结: -注解相当于一种标记,加类注解就等于打上类某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的包类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加的包,类,字段,方法,方法的参数以及局部变量上。 -看java.lang包,可看到JDK中提供的基本的annotation。
注解的应用结构图
自定义注解及其应用·定义一个最简单的注解:public @interface MyAnotation{}·把它加在某个类上:@MyAnnotation public class AnnotationTest{}·用反射进行测试AnnotationTest的定义上是否有@MyAnnotation·根据反射测试的问题,引出@Retention元注解的讲解,其三种取值:RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME;分别对应:java源文件-->class文件-->内存中的字节码。 -思考:@Override、@SuppressWarnings和@Deprecated这三个注解的属性值分别是什么? @Override->SOURCE、@SuppressWarnings->SOURCE、@Deprecated->RUNTIME·演示和讲解@Target元注解 -Target的默认值为任何元素,设置Target等于ElementType.METHOD,原来加在类上的注解就报错类,改为用数组方式设置{ElementType.METHOD,ElementType.TYPE}就可以了。·元注解以及其枚举属性值不用记,只要会看JDK提供那几个基本注解的API java.lang.annotation包下面的类。java.lang.annotation 枚举 ElementType枚举常量摘要 ANNOTATION_TYPE 注释类型声明 CONSTRUCTOR 构造方法声明 FIELD 字段声明(包括枚举常量) LOCAL_VARIABLE 局部变量声明 METHOD 方法声明 PACKAGE 包声明 PARAMETER 参数声明 TYPE 类、接口(包括注释类型)或枚举声明
为注解增加基本属性·什么事注解的属性 -一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是传智播客的学生,否则,就不是。如果还想区分出是传智播客哪个班的学生,这时候可以为胸牌再增加一个属性来进行区分。加类属性的标记效果为:@MyAnnotation(color="red")·定义基本类型的属性和应用属性: -在注解类中增加String color(); -@MyAnnotation(color="red")·用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法 -MyAnnotation a = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class); -System.out.println(a.color()); -可以认为上面的这个@MyAnnotation是MyAnnotation类的是个实例对象。·为属性指定缺省值: -String color() default "yellow";·value属性: -String value() default "zxx"; -如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略value=部分,例如:@MyAnnotation("lhm")。package lqq.heima.day2;
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 ItcastAnnotation { public abstract String color() default "blue"; public abstract String value() default "null";
}package lqq.heima.day2;
@ItcastAnnotation("red")public class AnnotationTest {
/** * @param args */ //@SuppressWarnings("deprecation") public static void main(String[] args) { // TODO Auto-generated method stub System.runFinalizersOnExit(true); if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)) { ItcastAnnotation ia = (ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class); System.out.println(ia.color()); System.out.println(ia.value()); }
} @Deprecated @ItcastAnnotation("value") public static void sayHello(){ System.out.println("hello,heima!"); }
}为注解增加高级属性·数组类型的属性 -int[] arrayAttr() default{1,2,3}; -@MyAnnotation(arrayAttr={2,3,4}) -如果数组属性中只有一个元素,这个时候属性值部分可以省略大括号·枚举类型的属性 -EnumTest.TrafficLamp lamp(); -@MyAnnotaion(lamp=EnumTest.TrafficLamp.GREEN)·注解类型的属性: -MetaAnnotaion annotationAttr() default @MetaAnnotation("xxxx"); -@MyAnnotation(annotationAttr=@MetaAnnotation("yyy")) -可以认为上面这个@MyAnnotation是MyAnnotation类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是 MetaAnnotation类的一个实例对象,调用代码如下: MetaAnnotation ma = myAnnotation.annotationAttr(); System.out.println(ma.value());·注解的详细语法可以通过看java语言规范了解,即看java的language specification。package lqq.heima.day2;
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import java.lang.reflect.Type;
import lqq.heima.day1.EnumTest;
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD,ElementType.TYPE})public @interface ItcastAnnotation { public abstract String color() default "blue"; public abstract String value() default "default value"; public abstract int[] arrayAttr()default {4,5,6}; public abstract EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED; public abstract MetaAnnotation metaAnnotationAttr() default @MetaAnnotation("default"); public abstract Class classAttr() default String.class ;
}package lqq.heima.day2;
import lqq.heima.day1.EnumTest;
@ItcastAnnotation(classAttr=Integer.class,arrayAttr={1,2,3},value="red",lamp=EnumTest.TrafficLamp.YELLOW,metaAnnotationAttr=@MetaAnnotation("flx"))public class AnnotationTest {
/** * @param args */ //@SuppressWarnings("deprecation") public static void main(String[] args) { // TODO Auto-generated method stub System.runFinalizersOnExit(true); if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)) { ItcastAnnotation ia = (ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class); System.out.println(ia.color()); System.out.println(ia.value()); System.out.println(ia.arrayAttr().length); System.out.println(ia.lamp().nextLamp().name()); System.out.println(ia.metaAnnotationAttr().value()); System.out.println(ia.classAttr().getName()); }
} @Deprecated @ItcastAnnotation("value") public static void sayHello(){ System.out.println("hello,heima!"); }
}