注解"1.5高新特性"(重点) 注解是一种注释类型的"接口" java提供的三个最基本的注解接口,位于java.lang包 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。 在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。 @Override 表示该方法覆盖父类方法,如果没有覆盖编译器会发出警告 @SuppressWarnings 在注释元素中取消指定的警告 注解相当于一种标记,为程序加上某种标记后,javac编译器,开发工具和其它程序可以通过反射来了解 这个类及各种元素上有无何种标记,这对这些标记做出相应的反应和操作。 标记可以加在包、类、字段、方法、方法的参数及局部变量上 注解相当于源程序中要调用的一个类,,要在源程序中应用某个注解,就要先准备好这个注解类 就像要调用哪个类,就要先准备好这个类一样。可以认为每个 @Xxx 就是这个注解类的实例对象 注解的应用: @interface A{} //A:注解类 @A class B{} //B:应用了注解的类 class C{//C:对应用了注解进行反射操作的类 B.class.isAnntionPresent(A.class); //判断该注解是否存在 A a = B.class.getAnnotion(A.class); //反射获取该注解的实例对象 } 元注解 在注解上添加的注解 Java中用两个元注解 Retention & Target 分别来控制注解的生命周期和使用范围 元数据,元信息... 注解的定义与反射调用 定义一个最简单的注解:public @interface MyAnnotation {} 把它加在某个类上:@MyAnnotation public class AnnotationTest{} 用反射进行测试AnnotationTest的定义上是否有@MyAnnotation 通过反射测试了解"元注解"的概念, Retention 元注解的三种取值:@ReflectionPolicy.[SOURCE、CLASS、RUNTIM] 分别对应 java源文件-->class文件-->内存中字节码 三个阶段。 用来控制注解的作用周期,默认为 CLASS 阶段;如果想让注解在其它阶段保存,就需要通过元注解来控制 Target 元注解用来限定注解的适用范围 @Target({ElementType.METHOD,ElementType.TYPE})//限定只能应用在方法和类|接口上 元注解的元素都是通过枚举的方式来获取的 //枚举使取值限定 且不可修改 判断java提供的注解的 属性值 Retention & Target @Override SOURCE //作用于编译阶段,由编译器检查 @SuppressWarnings SOURCE @Deprecated RUNTIM //在内存中检查二进制字节码 "为注解增加基本属性" 注解的属性:注解是一个标志,例如通过胸牌可以区分你是否在这个公司上班,如果还想区分你在哪个部门 就需要在胸牌上增加一个属性来区分。加属性的标识效果如: @MyAnnotation(color = "Yellow") 定义基本属性和应用属性 在注解类中定义属性 String color() 应用属性 @MyAnnotation(color = "Yellow") 属性应用,简写 String value() default "default";//默认缺省值 如果注解中有一个名称为value的属性,且你只想设置value属性,即其他属性都采用默认值或者你只有 一个value属性,那么可以省略value=部分,例如:@MyAnnotation("hello")。 数组类型的属性 int[] arrAttr() default{1,2,3}; //定义属性 @MyAnnotation(arrAttr = {6,7,8})//应用属性 如果数组属性中只有一个元素,应用时可以省略{} 枚举类型的属性 EnumeTest.TrafficLamp lamp(); @MyAnnotation(lamp = EnumTest.TrafficLamp.YELLOW) 注解类型的属性 //元注解类型的属性,缺省值为该注解的一个实例 MetaAnnotation annotationAttr() default @MetaAnnotation("default"); @MyAnnotation(annotationAttr = @MetaAnnotation("anno")) Class类型的属性 Class<?> a() default String.class;//即该注解属性返回一个Class @MyAnnotation(a=int.class) 更多注解的详细语法可以通过java语言规范了解,即java的language specification
元注解
public @interface MetaAnnotation { String value(); }
自定义注解
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import itheima.enhance.EnumTest; @Retention(RetentionPolicy.RUNTIME) //元注解设置为RUNTIM //将该注解限定为 仅能定义在 方法及类上 ,TYPE是Class与Interface的父类 @Target({ElementType.METHOD,ElementType.TYPE}) public @interface MyAnnotation { //相当于一个属性 (方法),返回类型为String String color() default "blue"; //设置默认缺省值,缺省属性要放在其他属性前面 String value(); int[] arrAttr()default {6,7,8}; //枚举类型的属性,缺省为该枚举中的一个元素 EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED; //元注解类型的属性,缺省值为该注解的一个实例 MetaAnnotation annotationAttr() default @MetaAnnotation("default"); //Class类型的属性 Class<?> a() default String.class; }
注解的应用
//自定义注解 属性 @MyAnnotation(a=int.class, annotationAttr=@MetaAnnotation("注解类型属性"), color="Yellow", value="haha",arrAttr=1) public class AnnotationTest { //特殊的属性,只有一个属性需要设置时,可以省略 "value=" @SuppressWarnings("deprecation") @MyAnnotation(value = "hello") public static void main(String[] args) { System.runFinalizersOnExit(true);//过时的方法 // 用反射方式获取注解对应的实例对象,通过该对象调用该属性对应的方法 if (AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){ MyAnnotation annotation = (MyAnnotation) AnnotationTest.class.getAnnotation(MyAnnotation.class); System.out.println(annotation.color()); System.out.println(annotation.value()); System.out.println(annotation.arrAttr().length);//数组 System.out.println(annotation.lamp().nextLamp().name());//枚举 System.out.println(annotation.annotationAttr().value());//注解 } } // @SuppressWarnings("deprecation") @Deprecated //注解为过时方法 public static void sayHello(){ System.out.println("hello World!"); } }