注解 Annotation
Annotation是一个接口,程序可以通过反射来获取指定程序元素的Annotation对象,然后通过Annotation对象来获取注解里面的元数据。
注解API非常强大,被广泛应用于各种Java框架,如Spring,Hibernate,JUnit。
- 定义:可以对程序作出解释(eg:注释)——但可以被其他程序(比如:编译器等)读取
- 格式:@+注释名
eg:@SuppressWarnings(value="unchecked")
注意事项
- 用途:通过标注包 类 字段 方法 局部变量 方法参数等告诉JVM它们的附加信息
- 使用:对于位置 语法 内容有严格的要求 错误的话程序编程过程中会出现异常
- 编译过程:通过反射获取程序员为某个元素标注的注解
- 大多数框架中常使用注解
- 注解分类:内置注解 元注解 自定义注解
内置注解
- java.lang.lang包下
- JDK给程序提供的额三种内置注解
@Override——重写方法
- 判断:编译器会检查你用@Override注解修饰的方法是不是父类的方法,如果父类没有这个方法 程序会报错
@Deprecated——已过时的
- 此注解可以用于修辞方法 , 属性 , 类 , 表示不鼓励程序员使用这样的元素 , 通常是因为它很危险或者存在更好的选择 它修饰的属性、方法等都不建议使用
- 不建议使用不代表不能用。最好不要用。一般都会有替代方式。如果你用了它
修饰的方法,一般会报一个警告。
@SuppressWarnings——压制警告、镇压警告
- 此注解可以用于修饰类,方法,方法参数,属性,局部变量。
- 作用:抑制编译时的警告信息 需要自己传入一个参数
eg:@SuppressWarnings(“all”)
eg:@SuppressWarnings(“unchecked”)
练习内置注解
import java.util.ArrayList;
import java.util.Date;
public class Demo {
public static void main(String[] args) {
int date = new Date().getDate();
System.out.println(date);
}
@Deprecated ——————表示这是方法不建议程序员使用
public int test() {
System.out.println("aaaaa");
return 1;
}
@SuppressWarnings("all") ——————灰色表示未被使用 加上注解后灰色消失
public String Hello(){
ArrayList<Object> list = new ArrayList<>();
return "hello";
}
@Override —————— 表示重写了Object类的方法oString()
public String toString(){
return "123456";
}
}
元注解
- java.lang.annotation包下
- 作用:负责注解其他注解 ————声明在其他注解上
@Target ——注解适用范围
ElementType.CONSTRUCTOR——描述构造器
ElementType.FIELD——描述域
ElementType.LOCAL_VARIABLE——描述局部变量
ElementType.METHOD——描述方法
ElementType.PACKAGE——描述包
ElementType.PARAMETER——描述参数
ElementType.TYPE——描述类、接口(包括注解类型) 或enum声明
@Retention ——注解的生命周期
RetentionPolicy.OURCE——在源文件中有效(即源文件保留)
RetentionPolicy.CLASS——在class文件中有效(即class保留)
RetentionPolicy.RUNTIME——在运行时有效(即运行时保留)
@Document——注解将被包含在javadoc中
@Inherited——子类可以继承父类中的该注解
练习元注解
import java.lang.annotation.*;
public class YuanDemo {
private int age;
@MyAnnotation
private int getAge(){
return age;
}
}
@Target(ElementType.METHOD) //表示这个注解能够注解的范围——方法
@Retention(RetentionPolicy.RUNTIME) // 表示这个注解能够在运行期生效
@Documented //表示注解可以在JavaDoc中生成信息
@Inherited // 表示子类可以继承父类的注解
@interface MyAnnotation { }
自定义注解——需要参数
- 自动继承了java.lang.annotation.Annotation接口
- 格式 : public @ interface 注解名 { 定义内容 }
若在类中声明注解 则去掉public
- 每一个方法实际上是声明了一个配置参数.
————方法的名称就是参数的名称
eg: String name();————name()是参数名
- 返回值类型就是参数的类型 ( 返回值只能是基本类型,Class , String , enum ).
- 可以通过default来声明参数的默认值
eg:int age() default 20;
——————名字参数默认为20 - 如果只有一个参数成员 , 一般参数名为value
eg:String[ ] value();
——————只有value可以爱赋值时省略参数名直接赋值 - 注解元素必须要有值 , 我们定义注解元素时 , 经常使用空字符串,0作为默认值 .
练习自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class ZiDingYiDemo {
private int age;
———————— 注解可以显示赋值 有默认值可以不赋值 若没有默认值 必须给注解赋值
@MyAnnotation1(name = "ZY",age = 20,id = 001,School = {"XiAnUniversity","清华北大"})
public void test(){}
@MyAnnotation2("ZY") // 只有一个参数value时 赋值可以省略参数名 (只能是value)
public void test1(){}
}
@Target({ElementType.ANNOTATION_TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation1 {
// 注解的参数:参数类型+参数名()
String name();//方法的名称就是参数的名称
/* String name() default "";————设置为默认 不需要参数 */
int age() default 0;
int id() default -1; //默认值为-1时 不存在
String[] School();
}
@Target({ElementType.ANNOTATION_TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
String[] value();// 只有一个参数时 建议用value()命名
}