注解

注解

_

什么是注解

Annotation是java5.0开始引入的新技术

Annotation的作用:
不是程序本身,可以对程序作出解释。
可以被其他程序(比如编译器)读取。

Annotation的格式:
注解是以"@注释名"在代码中存在的,还可以添加一些参数值,例如:@SuppressWarnings(value="unchecked").

Annotation在哪里使用?
可以附加在package、class、method、field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问。

内置注解

Override:定义在java.lang.Override中,此注解只适用于修饰方法,表示一个方法声明打算重写超类中的另一个方法声明。

@Deprecated:定义在java.lang.Deprecated中,此注解用于修辞方法,属性,类表示不鼓励程序员使用这样的元素,通常因为他们很危险或者存在更好的选择。
注释@Deprecated的程序元素是程序员不鼓励使用的程序元素。 由于多种原因,元素可能会被弃用,例如,它的使用可能会导致错误; 它可能会在以后的版本中不兼容地更改或删除; 它已被一种更新的,通常更可取的替代品取代; 或者它已经过时了。

@SuperessWarnings:定义在java.lang.SuperessWarnings中,用来抑制编译时的警告信息,与前两个注解不同,你需要添加一个正确的参数才能正确使用,这些参数都是定义好了的,我们选择使用就好了。
@SuperessWarnings("all")
@SuperessWarnings("unchecked")
@SuperessWarnings(value={"unchecked",deprecation})
等等~~

元注解

元注解顾名思义我们可以理解为注解的注解,它是作用在注解中,方便我们使用注解实现想要的功能。元注解分别有@Retention、 @Target、 @Document、 @Inherited 和 @Repeatable(JDK1.8加入)五种

@Retention

  • Retention英文意思有保留、保持的意思,它表示注解存在阶段是保留在源码(编译期),字节码(类加载)或者运行期(JVM中运行)。在@Retention注解中使用枚举RetentionPolicy来表示注解保留时期
  • @Retention(RetentionPolicy.SOURCE),注解仅存在于源码中,在class字节码文件中不包含
  • @Retention(RetentionPolicy.CLASS), 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
  • @Retention(RetentionPolicy.RUNTIME), 注解会在class字节码文件中存在,在运行时可以通过反射获取到
  • 如果我们是自定义注解,则通过前面分析,我们自定义注解如果只存着源码中或者字节码文件中就无法发挥作用,而在运行期间能获取到注解才能实现我们目的,所以自定义注解中肯定是使用 @Retention(RetentionPolicy.RUNTIME)

@Target

  • Target的英文意思是目标,这也很容易理解,使用@Target元注解表示我们的注解作用的范围就比较具体了,可以是类,方法,方法参数变量等,同样也是通过枚举类ElementType表达作用类型
  • @Target(ElementType.TYPE) 作用接口、类、枚举、注解
  • @Target(ElementType.FIELD) 作用属性字段、枚举的常量
  • @Target(ElementType.METHOD) 作用方法
  • @Target(ElementType.PARAMETER) 作用方法参数
  • @Target(ElementType.CONSTRUCTOR) 作用构造函数
  • @Target(ElementType.LOCAL_VARIABLE)作用局部变量
  • @Target(ElementType.ANNOTATION_TYPE)作用于注解(@Retention注解中就使用该属性)
  • @Target(ElementType.PACKAGE) 作用于包
  • @Target(ElementType.TYPE_PARAMETER) 作用于类型泛型,即泛型方法、泛型类、泛型接口 (jdk1.8加入)
  • @Target(ElementType.TYPE_USE) 类型使用.可以用于标注任意类型除了 class (jdk1.8加入)
  • 一般比较常用的是ElementType.TYPE类型

@Documented

  • Document的英文意思是文档。它的作用是能够将注解中的元素包含到 Javadoc 中去。

@Inherited

  • nherited的英文意思是继承,但是这个继承和我们平时理解的继承大同小异,一个被@Inherited注解了的注解修饰了一个父类,如果他的子类没有被其他注解修饰,则它的子类也继承了父类的注解。

@Repeatable

  • Repeatable的英文意思是可重复的。顾名思义说明被这个元注解修饰的注解可以同时作用一个对象多次,但是每次作用注解又可以代表不同的含义。
/**一个人喜欢玩游戏,他喜欢玩英雄联盟,绝地求生,极品飞车,尘埃4等,则我们需要定义一个人的注解,他属性代表喜欢玩游戏集合,一个游戏注解,游戏属性代表游戏名称*/

import java.lang.annotation.*;

/**玩家注解*/
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Documented
@Retention(RetentionPolicy.RUNTIME)
@interface People{
    Game[] value();
}

/**游戏注解*/
@Repeatable(People.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@interface Game{
    String gameName() default "";

}

/**玩游戏类*/
@Game(gameName = "LOL")
@Game(gameName = "PUBG")
@Game(gameName = "qq糖")
public class PlayGame {
    public static void main(String[] args) {
        People people = PlayGame.class.getAnnotation(People.class);
        for (Game g:people.value()) {
            System.out.println(g);
        }
    }
}

自定义注解

public @interface MyAnnotation 使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口。

//@Target() 表示注解可以用在哪些地方
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//注解在什么地方有效,我们一般都用RUNTIME。(RUNTIME>CLASS>SOURCE)
@Retention(RetentionPolicy.RUNTIME)
//@Documented表示是否将我们的注解生成在javadoc中
@Documented
//子类可以继承父类的注解
@Inherited
public @interface MyAnnotation {

    //注解参数:参数类型+参数名
    //定义一个名为value的String类型的参数,默认值为"",有默认值在使用注解的时候可以不用填写参数,没有默认值,就必须填写参数,不然就会报错
    String value() default "";
    
    String [] address() default {"上海","北京"};

}

泛型 2021-02-23
反射 2021-02-24

评论区