注解"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!");
}
}