我们为什么需要注解?
注解Annotation,是从JDK5.0开始引入的技术。用于对程序做出解释,并且可以被其他程序读取。
使用注解,可以方便阅读程序、减少重复代码、并结合反射等技术实现Java的动态性等。
常见内置注解
@Override
定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法打算重写父类中的另一个方法。若不是重写的方法,则会报错。
在《方法、方法的重载(Overload)与重写(Override)》一篇中,有详细的使用。
@Deprecated
定义在java.lang.Deprecated中,此注释可用于修辞方法、属性、类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择,并不是完全不能使用。
当我们在方法前加上@Deprecated注解时,调用该方法,方法名会被划删除线:test() 。即,我们平时若是使用到了被划线的方法,应该想办法避免使用。代码示例:
@Deprecated
public static void test(){
System.out.println("@Deprecated,test");
}
@SuppressWarnings
定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息。源码如下:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
String[] value();
并不是声明了一个数组变量,而是表示在使用时,需要添加一个String[ ]类型参数,用来明确抑制警告的范围,参数说明如下:
参数 | 说明 |
---|---|
deprecation | 使用了过失的类或方法警告 |
unchecked | 使用了未检查的转换警告,如集合未指定泛型 |
fallthrough | 在使用switch时,发生case穿透 |
path | 路径不存在的警告 |
serial | 可序列化的类缺少serialVersionUID的警告 |
finally | finally子句不能完成时的警告 |
all | 以上所有情况的警告 |
自定义注解
使用@interface来自定义注解,自定义注解会自动继承了java.lang.annotation.Annotation接口。
基本格式为:public @interface 注解名 {定义体}
,与类、接口等一样,一个java文件只能定义一个注解,且文件名需与注解命一致。
元注解
要想玩转自定义注解,就不得不提四个元注解:@Target、@Retention、@Documented、@Inherited。
元注解,就是负责注解其他注解的注解。主要使用的元注解为@Target与@Retention。
@Target,用于描述注解的使用范围。示例:@Target(value=ElementType.TYPE)
表示该注解可以用于在类、接口、枚举、注解上。全部值及说明:
取值ElementType | 修饰范围 |
---|---|
PACKAGE | package包 |
TYPE | 类、接口、枚举、注解 |
CONSTRUCTOR | 构造器 |
METHOD | 方法 |
FIELD | 字段 |
LOCAL_VARIABLE | 局部变量 |
PARAMETER | 参数 |
@Retention,用于表示在什么级别保存注解信息,描述注解的声明周期,取值说明:
取值RetentionPolicy | 作用 |
---|---|
SOURCE | 在源文件中有效 |
CLASS | 在class文件中有效 |
RUNTIME | 在运行时有效(可被反射读取) |
在使用Eclipse创建文件时,可以直接选择new Annotation。来个自定义注解案例:
//自定义注解
@Target(value={ElementType.FIELD}) //该注解只能描述字段
@Retention(RetentionPolicy.RUNTIME) //运行时有效,可以被反射读取
public @interface AnnField {
String columnName(); //使用时,需要传入三个参数
String type();
int length();
}
//自定义注解
@Target(value={ElementType.TYPE}) //该注解能描述类、接口、枚举、注解
@Retention(RetentionPolicy.RUNTIME) //运行时有效,可以被反射读取
public @interface AnnTable {
String value(); //使用时,需要传入一个参数
}
@Getter
@Setter //使用lombok,注解生成get、set方法(参考文章:https://blog.csdn.net/HhmFighting/article/details/104945023)
@AnnTable(value="t_student") //使用自定义注解
public class Student {
@AnnField(columnName="id",type="int",length=10)
private int id;
@AnnField(columnName="sname",type="varchar",length=10)
private String studentName;
@AnnField(columnName="age",type="int",length=3)
private int age;
}
注解与反射
通过反射机制,读取定义的注解,才是将自定义注解真正使用了起来。
可以参考我这篇博客:《反射》