首页 > 技术文章 > Java注解

goodluckya 2020-04-22 13:49 原文

1.1 什么是注解

  • Annotation是从JDK5.0开始引入的新技术
  • Annotation的作用:
    • 不是程序本身,可以对程序作出解释(类似于注释(comment))
    • 可以被其它程序(比如:编译器等)读取
  • Annotation的格式:
    • 注解是以"@注释名"在代码中存在的,还可以添加一些参数值
    • 例如:@SuppressWarnings(value="unchecked")
  • Annotation在哪里使用?
    • 可以附加在package、class、method、field等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问

1.2 内置注解

作用在代码的注解是

  • @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
  • @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
  • @SuppressWarnings - 指示编译器去忽略注解中声明的警告。

1.3 元注解

作用在其他注解的注解(或者说 元注解)是:

  • @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
  • @Documented - 标记这些注解是否包含在用户文档中。
  • @Target - 标记这个注解应该是哪种 Java 成员。
  • @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

1.4 从 Java 7 开始,额外添加了 3 个注解:

  • @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
  • @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
  • @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

1.5 自定义注解

  • 使用@interface自定义注解时,自动继承了Java.lang.annotation.Annotation接口
  • 分析
    • [@interface](#)用来声明一个注解,格式:public @interface 注解名{定义内容}
    • 其中的每一个方法实际上就是声明了一个配置参数
    • 方法的名称就是参数的名称
    • 返回值类型就是参数的类型(返回值只能是基本类型,class、string、enum)
    • 可以通过default来声明参数的默认值
    • 如果只有一个参数成员,一般参数名为value
    • 注解元素必须要有值,我们定义注解元素时,经常使用空字符串、0作为默认值
public class Test02 {
    /**
     * 注解可以显示赋值,如果没有默认值,就必须给注解赋值
     */
    @MyAnnotation2(name = "Hello")
    public void test(){};
}

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
    //注解的参数:参数类型 + 参数名();
    String name() default "";
    int age() default 0;
    int id() default -1;//如果默认值为-1,表示不存在
    String[] schools() default {"A","B"};
}

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
    String value();
}

1.6 ORM

  • Object Relationship Mapping
    • 类和表结构对应
    • 属性和字段对应
    • 对象和记录对应
  • 利用注解和映射完成类和表结构的映射
public class Test11 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("study.reflection.Student2");
        //通过反射获得注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //获得注解的value的值
        tableTest tabletest = (tableTest)c1.getAnnotation(tableTest.class);
        String value = tabletest.value();
        System.out.println(value);
        //获得类指定的注解
        Field name = c1.getDeclaredField("name");
        FieldTest annotation = name.getAnnotation(FieldTest.class);
        System.out.println(annotation.columnName());
        System.out.println(annotation.length());
        System.out.println(annotation.type());
    }
}

@tableTest("db_student")
class Student2 {
    @FieldTest(columnName = "db_name",type="varchar",length=3)
    private String name;
    @FieldTest(columnName = "db_id",type="int",length=10)
    private int id;
    @FieldTest(columnName = "db_age",type="int",length=10)
    private int age;

    public Student2() {
    }
    public Student2(String name, int id, int age) {
        this.name = name;
        this.id = id;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student2{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }
}

/**
 * @author zhao
 * 类名的注解
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface tableTest{
    String value();
}
/**
 * @author zhao
 * 属性的注解
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldTest{
    String columnName();
    String type();
    int length();
}

推荐阅读