JAVA基础--注解(Annotation)

JAVA基础--注解(Annotation)

一、概念

注解:提供一种为程序提供元数据(metadata)的方法
基本原则:注解不能直接干扰程序代码的运行,无论删除还是增加注解,代码都能够正常运行。

注解元素数据类型:

  • 所有基本类型
  • String
  • Class
  • enum
  • Annotation
  • 以上类型的数组

应用:

1、编写文档:通过代码里标识的元数据生成文档
2、代码分析:通过代码里标识的元数据对代码进行分析
3、编译检查:通过代码里标识的元数据让编译器能进行基本的编译检查,如@Override

二、标准注解

@Override

保证编译时候Override函数的申明正确性

@Deprecated

标记过时方法,如果使用该注解,编译时会报编译警告
与javadoc里的@deprecated有相同的功能,准确的说它还不如@deprecated,因为它不支持参数

@SuppressWarnings

关闭特定的警告信息

@SuppressWarnings(value={"unchecked", "rawtypes"})
class Test{
	@SuppressWarnings("unchecked")
	public void testMethod(){
		@SuppressWarnings("rawtypes")
		List list = new ArrayList();
	}
}

常见参数:

参数 含义
deprecation 关闭使用了过时的类或方法时的警告
unchecked 关闭执行了未检查的转换时的警告
fallthrough 关闭当switch程序块直接进入下一情况而未break的警告
path 关闭在类路径、源文件路径等中有不存在的路径时的警告
serial 关闭当在可序列化的类上缺少 serialVersionUID 定义时的警告
finally 关闭任何finally子句不能正常完成时的警告
all 关闭关于以上所有情况的警告

@FunctionalInterface

java8支持,标识一个匿名函数或函数式接口
函数式接口(Functional Interface)就是有且仅有一个抽象方法,但有多个非抽象方法的接口。

三、元注解

负责注解其他的注解

@Retention

表示需要在什么级别保存该注解信息

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

RetentionPolicy是一个枚举类型,它定义了被@Retention修饰的注解所支持的保留级别

生命周期类型 描述
RetentionPolicy.SOURCE 编译时被丢弃,不包含在类文件中
RetentionPolicy.CLASS JVM加载时被丢弃,包含在类文件中,默认值
RetentionPolicy.RUNTIME 由JVM加载,包含在类文件中,在运行时可以被获取到

@Target

该注解可以用于什么地方,指定作用域
源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

ElementType是一个枚举类型,它定义了被@Target修饰的注解可以作用的范围

Target类型 作用
TYPE 类、接口(包括注解类型)、枚举
FIELD 字段或属性(包括枚举)
METHOD 方法函数
PARAMETER 方法的参数
CONSTRUCTOR 构造函数
LOCAL_VARIABLE 局部变量
ANNOTATION_TYPE 注解类型
PACKAGE
TYPE_PARAMETER java8,类型变量
TYPE_USE java8,任何使用类型的语句中

@Documented

生成文档信息的时候保留注解,对类作辅助说明

@Inhertied

允许子类继承父类中的注释

@Repeatable

表示注解可以重复使用,java8新增
当我们需要重复使用某个注解时,希望利用相同的注解来表现所有的形式时,我们可以借助@Repeatable注解。

四、注解处理器

如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有作用了。使用反射机制的API可以帮助我们快速的构造自定义注解处理器。
提取注解:java.lang.reflect.AnnotatedElement接口

  • isAnnotationPresent 判断该程序元素上是否存在包含指定类型的注解,存在返回true,否则返回false;
  • getAnnotation 返回该程序元素上存在的指定类型的注解。如果该类型注解不存在,则返回null;
  • getAnnotations 返回该程序元素上存在的所有注解;
  • getAnnotationsByType 返回该程序元素上存在的指定类型的所有注解。如果该类型注解不存在,返回长度为0的数组。java8;
  • getDeclaredAnnotations 返回直接存在于此元素上的所有注解;
  • getDeclaredAnnotation 返回直接存在于此元素上的指定类型的注解。如果该类型注解不存在,则返回null。java8;
  • getDeclaredAnnotationsByType 返回直接存在于此元素上的指定类型所有注解 。如果该类型注解不存在,返回长度为0的数组。java8;

示例:

/** 自定义注解 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestAnnotation {
	public String name() default "";
}

/** 注解使用 **/
public class TestClass {
	@TestAnnotation(name = "测试")
	public void testMethod() {
		System.out.println(" testMethod run ");
	}
}

/** 注解处理器 **/
public class TestHandel{
	public static void main(String[] arg){
		Class clazz = TestClass.class;
		Method method = clazz.getMethod("testMethod");
		if(method.isAnnotationPresent(TestAnnotation.class)){
			TestAnnotation annotation = method.getAnnotation(TestAnnotation.class);
			// 打印注解属性
			System.out.println(annotation.name());
			// 控制新建的TestClass对象,执行 testMethod 方法
			method.invoke(new TestClass());
		}
	}
}
posted @   残忍的幻象饭团  阅读(113)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示