Java教程

Java注解(Annotation)

本文主要是介绍Java注解(Annotation),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.理解Annotation

  • jdk5.0 新增的功能
  • Annotation其实就是代码里的特殊标记,这些标记可以在编译,类加载、运行时被读取,并执行相应的处理,通过使用Annotation,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息
  • 在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等,在JavaEE/Android中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替JavaEE
  • 旧版中所遗留的繁冗代码和XML配置等。
  • 框架 = 注解 + 反射机制 + 设计模式

2.Annotation的使用示例

  • 示例一:生产文档相关的注解
    • @author 标明开发该类模块的作者,多个作者之间用,分割
    • @version 标明该类模块的版本
    • @see 参考转向,也就是相关主题
    • @since 从哪个版本开始增加的
    • @param 对方法中某参数的说明,如果没有参数就不能写
    • @return 对方法返回值的说明,如果方法的返回值类型是void就不能写
    • @exception 对方法可能抛出的异常进行说明,如果方法没有用throws显示抛出的异常就不能写其中
      • @param @return 和 @exception 这三个标记都是只能用于方法的
      • @param 的格式要求:@param 形参名 形参类型 形参说明
      • @return 的格式要求:@return 返回值类型 返回值说明
      • @exception 的格式要求:@exception 异常类型 异常说明
      • @param 和 @exception 可以并列多个
  • 示例二:在编译时进行格式检查(JDK内置三个基本注解)
    • @Override:限定重写父类方法,该注解只能用于方法
    • @Deprecated:用于表示所修饰的元素(类,方法)已超时,通常是因为所修饰的结构危险或存在更好的选择
    • @SuppressWarnings:抑制编译器警告
  • 示例三:跟踪代码依赖性,实现替代配置文件的功能

3.如何自定义注解:参照SuppressWarning定义

  • 注解声明为:@interface
  • 内部定义成员,通常使用value表示
  • 可以指定成员的默认值,使用default定义
  • 如果自定义注解没有成员,表明是一个标识作用
import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;

@Inherited
@Repeatable(MyAnnotations.class)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER, TYPE_USE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "hello";
}

说明:

  • 如果注解有成员,在使用注解时需要指明成员的值
  • 自定义注解必须配上注解的信息处理流程(使用反射)才有意义
  • 自定义注解通常都会指明两个元注解:Retention、Target

4.jdk提供的4种元注解

  • 元注解:对现有的注解进行解释说明的注解
  • Retention:指定所修饰的Annotation的生命周期,SOURCE/CLASS(默认行为)/RUNTIME,只有声明为RUNTIME生命周期的注解,才能通过反射获取
  • Target:用于指定被修饰的Annotation能用于修饰哪些程序元素
    • TYPE 意味着,它能标注"类、接口(包括注释类型)或枚举声明"。
    • FIELD 意味着,它能标注"字段声明"。
    • METHOD 意味着,它能标注"方法"。
    • PARAMETER 意味着,它能标注"参数"。
    • CONSTRUCTOR 意味着,它能标注"构造方法"。
    • LOCAL_VARIABLE 意味着,它能标注"局部变量"。
    • TYPE_PARAMETER 意味着,它能标注“类型参数声明”(jdk1.8新增)。
    • TYPE_USE 意味着,它能标注“使用一种类型”(jdk1.8新增)。
  • 以下的两个出现的频率较低
  • Documented:表示所修饰的注解在被javadoc解析时,保留下来
  • Inherited:被它修饰的Annotation将具有继承性
import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;

@Inherited
@Documented
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER, TYPE_USE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "hello";
}

5.如何获取注解信息

  • 通过反射来进行获取、调用 — 到反射内容时系统讲解
  • 前提:要求此注解的元注解Retention中声明的生命周期状态为:RUNTIME

6.jdk8中注解新特性:可重复注解、类型注解

6.1 可重复注解:

  • 在MyAnnotation上声明 @Repeatable,成员值为MyAnnotations.class
  • MyAnnotation的Target 和 Retention等元注解与MyAnnotation相同
import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;

@Inherited
@Repeatable(MyAnnotations.class)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER, TYPE_USE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "hello";
}
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;

@Inherited
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotations {
    MyAnnotation[] value();
}

@MyAnnotation(value = "world")
//jdk8 之前的写法
//@MyAnnotations({@MyAnnotation(value = "hello"),@MyAnnotation(value = "world")})
//jdk8 之后的写法
@MyAnnotation(value = "hello")
@MyAnnotation(value = "world")
class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void walk() {
        System.out.println("人走路");
    }

    public void eat() {
        System.out.println("人吃饭");
    }
}

6.2 类型注解:

  • ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)
  • ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中
import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;

@Inherited
@Repeatable(MyAnnotations.class)
@Target({TYPE_PARAMETER, TYPE_USE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "hello";
}
class Generic<@MyAnnotation T> {
    public void show() throws @MyAnnotation RuntimeException{
        ArrayList<@MyAnnotation String> list = new ArrayList<>();
        int num = (@MyAnnotation int) 10L;
    }
}
这篇关于Java注解(Annotation)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!