引言
做个俗人,贪财好色,一身正气。
JAVA注解是jdk1.5引入的一种注释机制。普通的注释从源文件编译成.class文件会被忽略,可以理解注释是给开发人员看的,而注解是给机器看的。
注解使用范围:类、方法、变量、参数以及包等。
一、内置注解
@Override : 重写 *
定义在java.lang.Override
@Deprecated:废弃 *
定义在java.lang.Deprecated
@FunctionalInterface: 函数式接口 *
Java 8 开始支持,标识一个匿名函数或函数式接口。
SuppressWarnings:抑制编译时的警告信息。 *
定义在java.lang.SuppressWarnings
三种使用方式
1. @SuppressWarnings("unchecked") [^ 抑制单类型的警告]
2. @SuppressWarnings("unchecked","rawtypes") [^ 抑制多类型的警告]
3. @SuppressWarnings("all") [^ 抑制所有类型的警告]
@SafeVarargs
Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
@Repeatable:标识某注解可以在同一个声明上使用多次
Java 8 开始支持,标识某注解可以在同一个声明上使用多次。
使用示范
public class test {
public static void main(String[] args) {
// 此方法已经被废弃,或多或少有bug,情况与系统线程的stop方法类似
new Person().setAge(1);
// 此注解加到哪里,对应的警告信息就不存在
@SuppressWarnings("all")
Person p = new Person();
}
// 先获取到方法,再获取到注解
@Override
public String toString() {
return super.toString();
}
}
class Person {
private int age;
public int getAge() {
return age;
}
/**
* 此方法已经废弃,通过setAge2调用
* @param age
*/
@Deprecated
public void setAge(int age) {
this.age = age;
}
public void setAge2(int age) {
this.age = age;
}
}
二、元注解
元注解:给自己定义的注解加上相应的配置。
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
@Documented - 标记这些注解是否包含在用户文档中 javadoc。
@Target - 标记这个注解应该是哪种 Java 成员。
@Inherited - 标记这个注解是自动继承的
1. 子类会继承父类使用的注解中被@Inherited修饰的注解
2. 接口继承关系中,子接口不会继承父接口中的任何注解,不管父接口中使用的注解有没有被@Inherited修饰
3. 类实现接口时不会继承任何接口中定义的注解
每 1 个 Annotation 对象,都会有唯一的 RetentionPolicy 属性;而 ElementType 属性,则有 1~n个。
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE, /* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该
Annotation /* 信息了 */
CLASS, /* 编译器将Annotation存储于类对应的.class文件中。默认行为 */
RUNTIME /* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
}
package java.lang.annotation;
public enum ElementType {
TYPE, /* 类、接口(包括注释类型)或枚举声明 */
FIELD, /* 字段声明(包括枚举常量) */
METHOD, /* 方法声明 */
PARAMETER, /* 参数声明 */
CONSTRUCTOR, /* 构造方法声明 */
LOCAL_VARIABLE, /* 局部变量声明 */
ANNOTATION_TYPE, /* 注释类型声明 */
PACKAGE /* 包声明 */
}
三、自定义注解
import java.lang.annotation.*;
@MyAnnotation(value = {"一", "二"}, num = 1)
public class Test {
public static void main(String[] args) {
}
}
// 注解是否包含在文档中
@Documented
// 用途类型
@Target(ElementType.TYPE)
// 保留策略
@Retention(RetentionPolicy.RUNTIME)
// 可以继承
@Inherited
@interface MyAnnotation {
/**
* 方法的名称就是 配置参数的名称
* 方法的返回值类型,就是配置参数的类型。只能是:基本类型/Class/String/enum
* 注解元素必须要有值,我们定义注解元素时,经常使用空字符串、0作为默认值。
* @return
*/
String[] value() default "";
int num() default 0;
}
四、反射获取注解
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
// 框架大部分内部原理
Class c = Class.forName("Book");
/*Annotation[] annotations = c.getAnnotations();
for (Annotation a : annotations) {
System.out.println(a);
}*/
TableAnnotation ta = (TableAnnotation) c.getAnnotation(TableAnnotation.class);
String value = ta.value();
System.out.println(value);
Field[] fs = c.getDeclaredFields();
for (Field f : fs) {
ColumnAnnotation ca = f.getAnnotation(ColumnAnnotation.class);
System.out.println(f.getName() + "属性对应数据库的字段:" + ca.columnName() + ",数据类型:" + ca.type() + ",数据长度:" + ca.length());
}
}
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface TableAnnotation {
/**
* 用于标注类对应的表名称
* @return
*/
String value();
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface ColumnAnnotation {
/**
* 描述列名
* @return
*/
String columnName();
/**
* 描述类型
* @return
*/
String type();
/**
* 描述长度
* @return
*/
String length();
}
@TableAnnotation("Test_Book")
class Book {
@ColumnAnnotation(columnName = "id", type = "int", length = "11")
private int id;
@ColumnAnnotation(columnName = "name", type = "varchar", length = "50")
private String name;
@ColumnAnnotation(columnName = "info", type = "varchar", length = "1000")
private String info;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", info='" + info + '\'' +
'}';
}
}
总结
人生无限,缓缓起航,修正改错,在满足完成任务的条件下,追求完善,全身而退。