【Java 基础】 注解
【Java 基础】 注解
Metadata
title: 【Java 基础】 注解
date: 2022-12-14 14:13
tags:
- 行动阶段/完成
- 主题场景/编程
- 笔记空间/KnowladgeSpace/ProgramSpace/BasicsSpace
- 细化主题/Java/基础
- 细化主题/注解
categories:
- Java
keywords:
- Java/基础
- 注解
description: 注解
作用
- 生成文档,通过代码里标识的元数据生成javadoc文档。
- 编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证。
- 编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码。
- 运行时动态处理,运行时通过代码里标识的元数据动态处理,例如使用反射注入实例。
分类
- Java自带的标准注解,包括@Override、@Deprecated和@SuppressWarnings,分别用于标明重写某个方法、标明某个类或方法过时、标明要忽略的警告,用这些注解标明后编译器就会进行检查。
- 元注解,元注解是用于定义注解的注解,包括@Retention、@Target、@Inherited、@Documented,@Retention用于标明注解被保留的阶段,@Target用于标明注解使用的范围,@Inherited用于标明注解可继承,@Documented用于标明是否生成javadoc文档。
- 自定义注解,可以根据自己的需求定义注解,并可用元注解对自定义注解进行注解。
内置注解
@Override
:表示当前的方法定义将覆盖父类中的方法@Deprecated
:表示代码被弃用,如果使用了被@Deprecated注解的代码则编译器将发出警告@SuppressWarnings
:表示关闭编译器警告信息
@Override
举例
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }
- 用来修饰方法
- 编译时有效
- 重写的父类的中的相同签名的方法
@Deprecated
举例
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
- 被文档化
- 保留到运行时
- 修饰构造方法、属性、局部变量、方法、包、参数、类型
告诉编译器被修饰的程序元素已被“废弃”,不再建议用户使用。
@SuppressWarnings
举例
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); }
- 修饰的程序元素包括类型、属性、方法、参数、构造器、局部变量
- 只能存活在源码时
- 取值为
String[]
告诉编译器忽略指定的警告信息
举例
参数 | 作用 | 原描述 |
---|---|---|
all | 抑制所有警告 | to suppress all warnings |
boxing | 抑制装箱、拆箱操作时候的警告 | to suppress warnings relative to boxing/unboxing operations |
cast | 抑制映射相关的警告 | to suppress warnings relative to cast operations |
dep-ann | 抑制启用注释的警告 | to suppress warnings relative to deprecated annotation |
deprecation | 抑制过期方法警告 | to suppress warnings relative to deprecation |
fallthrough | 抑制确在switch中缺失breaks的警告 | to suppress warnings relative to missing breaks in switch statements |
finally | 抑制finally模块没有返回的警告 | to suppress warnings relative to finally block that don’t return |
hiding | 抑制与隐藏变数的区域变数相关的警告 | to suppress warnings relative to locals that hide variable() |
incomplete-switch | 忽略没有完整的switch语句 | to suppress warnings relative to missing entries in a switch statement (enum case) |
nls | 忽略非nls格式的字符 | to suppress warnings relative to non-nls string literals |
null | 忽略对null的操作 | to suppress warnings relative to null analysis |
rawtype | 使用generics时忽略没有指定相应的类型 | to suppress warnings relative to un-specific types when using |
restriction | 抑制与使用不建议或禁止参照相关的警告 | to suppress warnings relative to usage of discouraged or |
serial | 忽略在serializable类中没有声明serialVersionUID变量 | to suppress warnings relative to missing serialVersionUID field for a serializable class |
static-access | 抑制不正确的静态访问方式警告 | to suppress warnings relative to incorrect static access |
synthetic-access | 抑制子类没有按最优方法访问内部类的警告 | to suppress warnings relative to unoptimized access from inner classes |
unchecked | 抑制没有进行类型检查操作的警告 | to suppress warnings relative to unchecked operations |
unqualified-field-access | 抑制没有权限访问的域的警告 | to suppress warnings relative to field access unqualified |
unused | 抑制没被使用过的代码的警告 | to suppress warnings relative to unused code |
元注解
@Target
作用
描述注解的使用范围(即:被修饰的注解可以用在什么地方)
Target注解用来说明那些被它所注解的注解类可修饰的对象范围:注解可以用于修饰 packages、types(类、接口、枚举、注解类)、类成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数),在定义注解类时使用了@Target
能够更加清晰的知道它能够被用来修饰哪些对象,它的取值范围定义在ElementType
枚举中。
ElementType
举例
public enum ElementType {
TYPE, // 类、接口、枚举类 FIELD, // 成员变量(包括:枚举常量) METHOD, // 成员方法 PARAMETER, // 方法参数 CONSTRUCTOR, // 构造方法 LOCAL_VARIABLE, // 局部变量 ANNOTATION_TYPE, // 注解类 PACKAGE, // 可用于修饰:包 TYPE_PARAMETER, // 类型参数,JDK 1.8 新增 TYPE_USE // 使用类型的任何地方,JDK 1.8 新增
}
@Retention & @RetentionTarget
作用
描述注解保留的时间范围(即:被描述的注解在它所修饰的类中可以被保留到何时) 。
用来限定那些被它所注解的注解类在注解到其他类上以后,可被保留到何时,一共有三种策略,定义在RetentionPolicy
枚举中。
RetentionPolicy
举例
public enum RetentionPolicy {
SOURCE, // 源文件保留 CLASS, // 编译期保留,默认值 RUNTIME // 运行期保留,可通过反射去获取注解信息
}
@Documented
作用
描述在使用 javadoc 工具为类生成帮助文档时是否要保留其注解信息。
@Inherited
作用
被它修饰的Annotation将具有继承性。如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解。
@Repeatable
作用
重复注解 ElementType.TYPE_USE
@Native
作用
使用 @Native 注解修饰成员变量,则表示这个变量可以被本地代码引用,常常被代码生成工具使用。对于 @Native 注解不常使用,了解即可
注解与反射接口
AnnotatedElement 接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通过反射获取了某个类的AnnotatedElement对象之后,程序就可以调用该对象的方法来访问Annotation信息。
boolean isAnnotationPresent(Class<?extends Annotation> annotationClass)
判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false。注意:此方法会忽略注解对应的注解容器。
<T extends Annotation> T getAnnotation(Class<T> annotationClass)
返回该程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。
Annotation[] getAnnotations()
返回该程序元素上存在的所有注解,若没有注解,返回长度为0的数组。
<T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass)
返回该程序元素上存在的、指定类型的注解数组。没有注解对应类型的注解时,返回长度为0的数组。该方法的调用者可以随意修改返回的数组,而不会对其他调用者返回的数组产生任何影响。getAnnotationsByType
方法与 getAnnotation
的区别在于,getAnnotationsByType
会检测注解对应的重复注解容器。若程序元素为类,当前类上找不到注解,且该注解为可继承的,则会去父类上检测对应的注解。
<T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass)
返回直接存在于此元素上的所有注解。与此接口中的其他方法不同,该方法将忽略继承的注释。如果没有注释直接存在于此元素上,则返回null
<T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass)
返回直接存在于此元素上的所有注解。与此接口中的其他方法不同,该方法将忽略继承的注释
Annotation[] getDeclaredAnnotations()
返回直接存在于此元素上的所有注解及注解对应的重复注解容器。与此接口中的其他方法不同,该方法将忽略继承的注解。如果没有注释直接存在于此元素上,则返回长度为零的一个数组。该方法的调用者可以随意修改返回的数组,而不会对其他调用者返回的数组产生任何影响。
自定义注解
-
注解实现的原理
注解的本质
注解是一个接口,一个继承自Annotation的接口。
里面每一个属性,其实就是接口的一个抽象方法。
这里推荐你两篇文章:
- https://blog.csdn.net/qq_20009015/article/details/106038023
- https://www.race604.com/annotation-processing/
注解的应用场景
配置化到注解化 - 框架的演进
Spring 框架 配置化到注解化的转变。
继承实现到注解实现 - Junit3到Junit4
一个模块的封装大多数人都是通过继承和组合等模式来实现的,但是如果结合注解将可以极大程度提高实现的优雅度(降低耦合度)。而Junit3 到Junit4的演化就是最好的一个例子。
自定义注解和AOP - 通过切面实现解耦
- 自定义Log注解
- 实现日志的切面, 对自定义注解Log作切点进行拦截