Java注解介绍

Java注解

    • 注解介绍
    • 元注解
      • @Retention
      • @Target
      • @Documented
      • @Inherited
        • 接口
        • 测试结果

注解介绍

Java注解(Annotation)是一种元数据(Metadata)的形式,它可以被添加到Java代码中的类、方法、变量、参数等元素上,以提供关于程序代码的额外信息。
在Java中,注解并不是一个Java类,而是一个特殊的接口类型(默认继承java.lang.annotation.Annotation接口),其实例在编译时被创建,并且在程序运行过程中可以通过反射获取相关信息。
注解里面定义的方法,代表的注解的成员属性,可以指定默认值(不指定默认值时,使用时必须指定对应的值)。在注解被使用时可以指定具体的的值,在编译时,会自动创建代理的注解对象,这个对象的属性不可修改(immutable)。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({OnClassCondition.class})
public @interface ConditionalOnClass {Class<?>[] value() default {};String[] name() default {};
}

在这里插入图片描述

元注解

Java中,元注解是用来修饰其它注解的注解。元注解是用来定义其它注解行为的注解。Java提供了常用的元注解:@Retention、@Target、@Documented、@Inherited。

@Retention

retention:保留;保持。
@Retention保留注解策略,只有这个元注解作用于注解时才有效;如果将元注解类型作用于另一个注解类型的成员属性(成员变量),则无效。
保留策略:RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME。

  • RetentionPolicy.SOURCE:注解在编译时会被丢弃。只保留在源代码级别,可以用于编译器的静态检查和处理。
  • RetentionPolicy.CLASS:注解被保留在class文件中,但是运行时不可见,不能通过反射获取。对编译器可见,但是运行时不会产生任何效果。缺省的默认保留策略。
  • RetentionPolicy.RUNTIME:编译后被保存在class文件中,并且运行时能提供反射获取到。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {// 返回注解保留的策略RetentionPolicy value();
}

继承Retention注解

package com.oycm.spring_data_jpa.annotations.retention;import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.SOURCE)
public @interface RetentionSource {
}
package com.oycm.spring_data_jpa.annotations.retention;import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.SOURCE)
public @interface RetentionClass {}
package com.oycm.spring_data_jpa.annotations.retention;import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)
public @interface RetentionRuntime {Class<RetentionClass> value();
}
package com.oycm.spring_data_jpa.annotations.retention;import java.lang.annotation.Annotation;
import java.lang.reflect.Field;/*** @author ouyangcm* create 2024/2/26 15:52*/
@RetentionSource
@RetentionClass
@RetentionRuntime(value = RetentionClass.class)
public class RetentionTest {@RetentionSource@RetentionClass@RetentionRuntime(value = RetentionClass.class)private String member;@RetentionSource@RetentionClass@RetentionRuntime(value = RetentionClass.class)private static String staticMember;public static void main(String[] args) {Class<RetentionRuntime> runtimeClass = RetentionRuntime.class;Class<RetentionTest> clazz = RetentionTest.class;Annotation[] annotations = clazz.getAnnotations();for (Annotation annotation : annotations) {System.out.println(annotation);}Field[] currentClassFields = clazz.getDeclaredFields();for (Field currentClassField : currentClassFields) {System.out.println("属性名: " + currentClassField.getName());Annotation[] fieldAnnotations = currentClassField.getAnnotations();for (Annotation fieldAnnotation : fieldAnnotations) {System.out.println("注解: " + fieldAnnotation.annotationType().getName());}}}
}

在这里插入图片描述
注意:反射获取的Annotation是一个代理对象,可以使用annotationType()方法获取真正的注解对象类信息。
在这里插入图片描述

@Target

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {// 注解目标类型数组ElementType[] value();
}

@Target注解用于指定注解可以应用的目标类型。类型有:ElementType.TYPE(类、接口(注解)、枚举等)、ElementType.FIELD(静态或非静态成员变量)、ElementType.METHOD(普通方法)、ElementType.PARAMETER(方法参数)、ElementType.CONSTRUCTOR(构造方法)、ElementType.LOCAL_VARIABLE(局部变量)、ElementType.ANNOTATION_TYPE(注解)、ElementType.PACKAGE(包)、ElementType.TYPE_PARAMETER(泛型)、ElementType.TYPE_USE(用于使用类型的任何地方)。

// 不能作用于其他类型上,只能作为其他注解的变量使用
@Target({})
public @interface MemberType {...
}// 类型重复出现,编译报错
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
public @interface Bogus {...
}

@Documented

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

指示被标注的自定义注解是否应该包含再Java文档中。一个注解使用了@Document注解标注,那么使用javadoc工具生成文档时,这个注解的信息会被包含在文档中。

@Inherited

Inherited:继承的;遗传的。
表示类的注解是可继承的,使用getAnnotation()会自动查询该类的父类以获取所有的注解,直到Object类;这个元注解只在作用于类注解时才生效。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
@Inherited
@Retention(RetentionPolicy.RUNTIME)// 不可省略,不然获取不到
@Target(ElementType.TYPE)
public @interface MyInherited {
}
接口
package com.oycm.spring_data_jpa.annotations.inherited;@MyInherited
public interface InheritedInterface {
}
package com.oycm.spring_data_jpa.annotations.inherited;/*** @author ouyangcm* create 2024/2/26 17:22*/
public class InheritedInterfaceImpl implements InheritedInterface{
}
package com.oycm.spring_data_jpa.annotations.inherited;/*** @author ouyangcm* create 2024/2/26 17:22*/
@MyInherited
public class InheritedSuper {
}
package com.oycm.spring_data_jpa.annotations.inherited;/*** @author ouyangcm* create 2024/2/26 17:22*/
public class InheritedSuperSub extends InheritedSuper{
}
测试结果
package com.oycm.spring_data_jpa.annotations.inherited;/*** @author ouyangcm* create 2024/2/26 17:21*/
public class InheritedTest {public static void main(String[] args) {Class<InheritedInterface> inheritedInterfaceClass = InheritedInterface.class;Class<InheritedInterfaceImpl> inheritedInterfaceClassImpl = InheritedInterfaceImpl.class;// 这里获取到Annotation对象仍然是代理,不过两个是同一个对象.annotationType()可以获取真正的Class对象System.out.println(inheritedInterfaceClass.getAnnotation(MyInherited.class));System.out.println(inheritedInterfaceClass.getDeclaredAnnotation(MyInherited.class));System.out.println(inheritedInterfaceClassImpl.getAnnotation(MyInherited.class));System.out.println(inheritedInterfaceClassImpl.getDeclaredAnnotation(MyInherited.class));Class<InheritedSuper> inheritedSuperClass = InheritedSuper.class;Class<InheritedSuperSub> inheritedSuperSubClass = InheritedSuperSub.class;System.out.println(inheritedSuperClass.getAnnotation(MyInherited.class));System.out.println(inheritedSuperClass.getDeclaredAnnotation(MyInherited.class));System.out.println(inheritedSuperSubClass.getAnnotation(MyInherited.class));System.out.println(inheritedSuperSubClass.getDeclaredAnnotation(MyInherited.class));// 只能获得自己的注解}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/730775.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一分钟带你入门Selenium入门!【建议收藏】

Selenium入门 欢迎阅读Selenium入门讲义&#xff0c;本讲义将会重点介绍Selenium的入门知识以及Selenium的前置知识。 自动化测试的基础 在Selenium的课程以前&#xff0c;我们先回顾一下软件测试的基本原理&#xff0c;为我们进一步完成Selenium自动化测试做好准备。 软件…

考研数学|张宇30讲,搭配什么基础题?

如果基础跟的是张宇&#xff0c;那么基础做的题目要根据自己的题目来决定 题集的选择最好不要太难&#xff0c;而且基础也不用做太多题目&#xff0c;以数学知识点的运用&#xff0c;培养做题感觉为主。 张宇老师的课程在基础阶段也有配套的课程&#xff0c;就是《张宇基础30…

2023郑州大学招新赛暨选拔赛补题

U287342 A.NANA与字符串 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) U287344 B.NANA学跳舞 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) U287345 C.NANA去上课 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include <bits/stdc.h> using namespace std; #de…

关于进程和线程

目录 前言: 1进程: 1.1定义&#xff1a; 1.1.1进程是操作系统分配资源的基本单元&#xff0c;拥有自己的独立空间和资源。 1.1.2每个进程都有一个唯一的PID&#xff08;进程标识符&#xff09;来标识。 1.2进程间通信&#xff1a; 1.2.1进程不是孤立的&#xff0c;它们之…

搜索引擎都没流量啦,官网建设还有啥意义?

百度等搜索引擎都没啥流量了&#xff0c;再建设官网还有啥用&#xff1f;如果你把官网定位于获客&#xff0c;那真的没啥太大用处&#xff0c;但是官网不仅仅是用来获客的。 一、搜索引擎的流量被稀释了 搜索引擎流量减少的原因有多个&#xff0c; 1. 社交媒体的崛起&#xf…

电机控制系列模块解析(第八篇)—— 高频注入法

一、基本原理 在电机控制领域&#xff0c;高频方波注入法常用于估计转子的位置和转速。其工作原理是每隔一定的时间间隔在电机输出电压上叠加一个电压脉冲。然后&#xff0c;在两相静止坐标系下或者同步旋转坐标系下对采样时刻的电压和电流进行相应的计算&#xff0c;以实现对…

基于Python3的数据结构与算法 - 11 基数排序

一、引入 多关键字排序&#xff1a;假如现在有一个员工表。要求按照薪资排序&#xff0c;薪资相同的员工按照年龄排序。 先按照年龄进行排序&#xff0c;再按照薪资进行稳定的排序 按照这种思路我们对[32,13,94,52,17,54,93]排序&#xff1a; 先比较十位数的数字大小&#…

JS-04-javaScript数据类型和变量

一、数据类型 计算机能处理的远不止数值&#xff0c;还可以处理文本、图形、音频、视频、网页等各种各样的数据&#xff0c;不同的数据&#xff0c;需要定义不同的数据类型。在JavaScript中定义了以下几种数据类型&#xff1a; 1-1、Number JavaScript不区分整数和浮点数&…

c++ set集合按位置(索引)查询元素的方法

在STL中集合好处是可以对输入的元素进行排序&#xff0c;就是说在某些情况下对某些需要有序的元素可以使用set集合存储。不过在set集合没有提供按值查询的方法。 在集合中&#xff0c;set集合不允许出现重复元素&#xff0c;使用multiset集合可以存储重复元素。 按位置查询 按…

RK平台内核解压方式

64 位平台 64 位平台的机器通常烧写Image&#xff0c;由U-Boot 加载到目标运行地址。但是 RK平台的 U-Boot 还可支持 对64位 LZ4格式的压缩内核进行解压。但是用户必须使能&#xff1a; CONFIG_LZ4y64位LZ4压缩内核的解压前、后地址必须定义在各平台的 rkxxx_common.h 文件中…

【C++】每日一题 128 最长连续序列

给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 #include <iostream> #include <vector> #include <unordered_set&g…

预训练模型的使用torchvision.model和timm

pytorch 自带的torchvision.models 加载已经下好的模型 如果您想在导入 ResNet-50 模型时指定 pretrainedFalse&#xff0c;表示不加载预训练权重&#xff0c;您可以按照以下方式进行&#xff1a; import torch import torchvision.models as models# 创建 ResNet-50 模型实…

目标检测——高压线绝缘子数据集

一、简介 绝缘子是电力系统中至关重要的部件,它承担着保障电力安全、可靠传输的重要任务。绝缘子的性能直接影响到高压输电线路的运行状态。绝缘子长期暴露在恶劣的自然环境中,如强风、雷电、高温、低温、盐雾等,这些环境因素都可能对绝缘子的性能产生不良影响,导致其出现…

西门子PLC的交互界面怎样设计?

西门子PLC的交互界面设计集中于提供一个直观、多功能且用户友好的环境&#xff0c;旨在使工程师和技术人员能够有效地进行编程、监控和维护。下面是一些设计西门子PLC交互界面时的关键考虑因素&#xff1a; 1. **图形化编程环境**&#xff1a;设计时&#xff0c;重点在于提供直…

关于Vivado的实施过程、SDC和XDC约束支持、Vivado实施子流程、Tcl API支持脚本

关于Vivado的实施过程 AMD Vivado™设计套件可实现以下AMD设备体系结构&#xff1a;AMD Versal™自适应计算加速平台&#xff08;自适应SoC&#xff09;&#xff0c;AMDUltraScale™、AMD UltraScale™和AMD 7系列FPGA。各种设计来源如下支持&#xff0c;包括&#xff1a; •…

【视频图像取证篇】模糊图片复原车牌号技术原理和实战应用小结

【视频图像取证篇】模糊图片复原车牌号技术原理和实战应用小结 模糊图片复原车牌号常用的技术原理和实战应用—【蘇小沐】 &#xff08;一&#xff09;运动模糊视频图像 由于各种各样的原因&#xff0c;主体或者拍摄设备运动共同造成的视频图像模糊等。 1、快门速度 快门速…

Vue事件处理:.passive修饰符与应用场景

.passive修饰符 passive这个修饰符会执行默认方法。你们可能会问&#xff0c;明明默认执行为什么会设置这样一个修饰符。这就要说一下这个修饰符的本意了。 浏览器只有等内核线程执行到事件监听器对应的JavaScript代码时&#xff0c;才能知道内部是否会调用preventDefa…

接口自动化测试用例的编写方法

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 phpunit 接口自动化测试系列 Post接口自动化测试用例 Post方式…

2007-2022年上市公司迪博内部控制评价缺陷数量数据

2007-2022年上市公司迪博内部控制评价缺陷数量数据 1、时间&#xff1a;2007-2022年 2、范围&#xff1a;上市公司 3、指标&#xff1a;证券代码、证券简称、辖区、证监会行业、申万行业、是否存在财报内控重大缺陷、财报内控重大缺陷数量、是否存在财报内控重要缺陷、财报内…

植物病害识别:YOLO甘蔗叶片病害识别分类数据集

YOLO甘蔗叶片病害识别数据集, 包含尾孢菌叶斑病&#xff0c;眼斑病&#xff0c;健康&#xff0c;红腐病&#xff0c;锈病&#xff0c;黄叶病6个常见病类别&#xff0c;3300多张图像&#xff0c;yolo标注完整&#xff0c;全部原始图像&#xff0c;未应用增强。 适用于CV项目&…