Java基础——注解

1 概述

注解用于对Java中类、方法、成员变量做标记,然后进行特殊处理,至于到底做何种处理由业务需求来决定。
例如,JUnit框架中,标记了注解@Test的方法就可以被当做测试方法进程执行

2 自定义注解

public @interface 注解名称 {public 属性类型 属性名() default 默认值;
}

属性类型支持Java中的所有数据类型
自定义注解

public @interface MyBook {String name();String[] authors();double price();
}

使用注解

@MyBook(name = "《Java基础1》", authors = "Bill", price = 123)
public class Main {public static void main(@MyBook(name = "《Java基础2》", authors = "Bill", price = 123) String[] args) {@MyBook(name = "《Java基础3》", authors = "Bill", price = 123)int i  = 3;System.out.println("Hello world!");}@MyBook(name = "《Java基础4》", authors = "Bill", price = 123)private Main() {}
}

注解可以标注类、形参、变量、方法。

3 注解的特殊属性

注解中有一个value属性,如果只有一个value属性的情况下,使用value属性的时候可以省略名称不写。
但是如果有多个属性,且多个属性没有默认值,那么value名称是不能省略的。

public @interface MyAnnotatin {String value();
}

使用时

@MyAnnotatin(value = "test")
public class Annotation {public static void main(String[] args) {System.out.println("test");}
}

可以省略value

@MyAnnotatin("test")
public class Annotation {public static void main(String[] args) {System.out.println("test");}
}

如果与value共存的有多个属性,则会报错

public @interface MyAnnotatin {String value();String name();
}

上面使用的代码会报错
在这里插入图片描述
如果name具有默认值,则又可以省略value,因为此时name是有值的,使用默认值。

public @interface MyAnnotatin {String value();String name() default "MyAnnotaion";
}

4 元注解

元注解就是注解注解的注解,元注解一共有四种。

  • @Target:描述注解的使用范围
  • @Retention:申明注解的生命周期
  • @Documented:描述在使用 javadoc 工具为类生成帮助文档时是否要保留其注解信息
  • @Inherited:被他修饰的注解具有继承属性

4.1 Target注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;@Target({ElementType.METHOD, ElementType.FIELD})
public @interface MyTest {
}

只能在方法和字段中使用,不能用于类等其他地方。
在这里插入图片描述

4.2 Retention注解

在这里插入图片描述

5 注解解析

注解的解析就是判断是否存在注解,存在注解就解析出内容
与注解解析相关的接口

  • Annotation:注解的顶级接口,注解都是Annotation类型的对象
  • AnnotatedElement:该接口定义了与注解解析相关的解析方法
    在这里插入图片描述
    所有的类成分Class,Method,Field,Constructor都实现了AnnotatedElement接口,他们都有解析注解的能力。
    解析技巧:
  • 注解在哪个成分上,我们就先拿哪个对象成分
  • 比如注解作用在成员方法,则现货区该方法对应的Method对象,再拿上面的注解
  • 注解在类上,先拿Class对象,再拿注解
  • 注解在成员变量上,先拿成员变量对应的Field对象,再拿注解

定义注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Bookk {String value();double price() default 100;String[] author();
}

解析注解

import org.junit.Test;import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;/**目标:完成注解的解析*/
public class AnnotationDemo3 {@Testpublic void parseClass(){// a.先得到类对象Class c = BookStore.class;// b.判断这个类上面是否存在这个注解if(c.isAnnotationPresent(Bookk.class)){//c.直接获取该注解对象Bookk book = (Bookk) c.getDeclaredAnnotation(Bookk.class);System.out.println(book.value());System.out.println(book.price());System.out.println(Arrays.toString(book.author()));}}@Testpublic void parseMethod() throws NoSuchMethodException {// a.先得到类对象Class c = BookStore.class;Method m = c.getDeclaredMethod("test");// b.判断这个类上面是否存在这个注解if(m.isAnnotationPresent(Bookk.class)){//c.直接获取该注解对象Bookk book = (Bookk) m.getDeclaredAnnotation(Bookk.class);System.out.println(book.value());System.out.println(book.price());System.out.println(Arrays.toString(book.author()));}}
}@Bookk(value = "《情深深雨濛濛》", price = 99.9, author = {"琼瑶", "dlei"})
class BookStore{@Bookk(value = "《三少爷的剑》", price = 399.9, author = {"古龙", "熊耀华"})public void test(){}
}

先拿对应对象,再拿注解属性,并进行对应的操作。

6 模拟Junit

注解

@Target({ElementType.METHOD}) // 元注解
@Retention(RetentionPolicy.RUNTIME) // 一直活着,在运行阶段这个注解也不消失
public @interface MyTest {
}

注解只作用于方法上,并且一直存活。
测试类

public class AnnotationDemo4 {public void test1(){System.out.println("===test1===");}@MyTestpublic void test2(){System.out.println("===test2===");}@MyTestpublic void test3(){System.out.println("===test3===");}/**启动菜单:有注解的才被调用。*/public static void main(String[] args) throws Exception {AnnotationDemo4 t = new AnnotationDemo4();// a.获取类对象Class c = AnnotationDemo4.class;// b.提取全部方法Method[] methods = c.getDeclaredMethods();// c.遍历方法,看是否有MyTest注解,有就跑它for (Method method : methods) {if(method.isAnnotationPresent(MyTest.class)){// 跑它method.invoke(t);}}}
}

这里main方法作为一个启动按钮,因为junit与idea有合作,所以标识了@Test的都有一个启动按钮,而我们的注解没有,所以这里模拟一下。启动后获取方法列表,并判断哪个方法上有MyTest注解,有的则执行方法。

7 总结

  1. 注解作用是对类、方法、成员变量等做标记,并进行特殊处理
  2. 元注解是注解注解的注解,有四种元注解,分别为Target、Retention、Documented、Inherited。
  3. Target标识注解作用的对象
  4. Retention申明注解的生命周期,编译、字节吗还是运行时期一直存在。
  5. Documented标识使用javadoc生成说明时保留注解
  6. Inherited修饰的注解具有继承属性
  7. 注解解析就是对注解内容进行解析。类相关的类,比如Class、Method、Filed等都实现了AnnotatedElement接口,所以,解析的时候,首先获得对象的对象,并调用判断方法判断注解是否存在,如果存在,则执行对应操作

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

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

相关文章

8.1 配置环境/Linux进程管理总结/Argument/saveload Module/切片

文章目录 一、配置环境二、Linux 进程管理总结三、ArgumentParser四、Saving and Loading Models nn.ModulesWarmstarting Model Using Parameters from a Different Model五、切片!拓展: 一、配置环境 github配置环境可以直接赋值到txt中,然…

一 关于idea如何在svn进行项目下载并运行成功

安装svn客户端 如图 安装时请选择该选项(Will be installed on local hard drive)并选择自己想要安装的目录路径 如图 svn安装成功 如图 注意 安装完成后,使用svn进行一次checkout的项目导出完成以上五步时&…

Qt应用开发(基础篇)——滑块类 QSlider、QScrollBar、QDial

一、前言 滑块类QScrollBar、QSlider和QDial继承于QAbstractSlider,父类主要拥有最大值、最小值、步长、当前值、滑块坐标等信息,滑动的时候触发包含值数据变化、滑块按下、滑块释放等信号。键盘包括左/上和右/下箭头键通过定义的singleStep改变当前值&a…

程序框架-事件中心模块-观察者模式

一、观察者模式 1.1 观察者模式定义 意图: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变是,所有依赖于它的对象都能得到通知并自动更新。 适用性: 当一个对象状态的改变需要改变其他对象, 或实际对…

大模型使用——超算上部署LLAMA-2-70B-Chat

大模型使用——超算上部署LLAMA-2-70B-Chat 前言 1、本机为Inspiron 5005,为64位,所用操作系统为Windos 10。超算的操作系统为基于Centos的linux,GPU配置为A100,所使用开发环境为Anaconda。 2、本教程主要实现了在超算上部署LLAM…

CentOS 安装 Jenkins

本文目录 1. 安装 JDK2. 获取 Jenkins 安装包3. 将安装包上传到服务器4. 修改 Jenkins 配置5. 启动 Jenkins6. 打开浏览器访问7. 获取并输入 admin 账户密码8. 跳过插件安装9. 添加管理员账户 1. 安装 JDK Jenkins 需要依赖 JDK,所以先安装 JDK1.8。输入以下命令&a…

【RabbitMQ(day4)】SpringBoot整合RabbitMQ与MQ应用场景说明

一、SpringBoot 中使用 RabbitMQ 导入对应的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>配置配置文件 spring:application:name: rabbitmq-springbo…

【解放ipad生产力】如何在平板上使用免费IDE工具完成项目开发

我的博客即将同步至腾讯云开发者社区&#xff0c;邀请大家一同入驻&#xff1a;https://cloud.tencent.com/developer/support-plan?invite_code3o19zyy2pneoo 前言 很多人应该会像我一样吧&#xff0c;有时候身边没电脑突然要写项目&#xff0c;发现自己的平板没有一点作用&…

[openCV]基于赛道追踪的智能车巡线方案V1

import cv2 as cv import os import numpy as npimport time# 遍历文件夹函数 def getFileList(dir, Filelist, extNone):"""获取文件夹及其子文件夹中文件列表输入 dir&#xff1a;文件夹根目录输入 ext: 扩展名返回&#xff1a; 文件路径列表""&quo…

❤ npm不是内部或外部命令,也不是可运行的程序 或批处理文件

❤ npm不是内部或外部命令,也不是可运行的程序 或批处理文件 cmd或者终端用nvm 安装提示&#xff1a; npm不是内部或外部命令,也不是可运行的程序或批处理文件 原因&#xff08;一&#xff09; 提示这个问题&#xff0c;有可能是Node没有安装&#xff0c;也有可能是没有配置…

Docker卸载安装及国内镜像源(详细版)

文章目录 一、卸载已有Docker1、首先判断本地有没有docker&#xff1a;2、判断CentOS下 docker是否在运行&#xff1a;3、停止docker运行&查看状态4、yum查看docker安装的包并卸载5、删除docker安装目录6、查看docker version 二、Docker安装及镜像源配置1、centOS 7 yum源…

钉钉群消息推送

1. 添加钉钉群机器人 PC端登录&#xff08;当前版本手机端无法进行推送关键词设置&#xff09;&#xff0c;群设置--> 机器人 --> webhook进行安全设置复制webhook对应的url 2. 群消息推送 钉钉群消息支持纯文本和markdown类型 2.1 调用示例源码 import com.alibaba.…

设计模式之模板方法

一、概述 定义一个操作中的算法的骨架&#xff0c;将一些步骤延迟到子类中。 TemplateMethod使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。 二、适用性 1.一次性实现一个算法的不变的部分&#xff0c;并将可变的行为留给子类来实现。 2.各子类中公共…

人机交互与人机混合智能的区别

人机交互和人机融合智能是两个相关但不完全相同的概念&#xff1a; 人机交互是指人与计算机之间的信息交流和互动过程。它关注的是如何设计和实现用户友好的界面&#xff0c;以便人们能够方便、高效地与计算机进行沟通和操作。人机交互通常强调用户体验和界面设计&#xff0c;旨…

6.7.tensorRT高级(1)-使用onnxruntime进行onnx模型推理过程

目录 前言1. python-ort2. C-ort总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-使用 onnxruntime 进行 on…

[openCV]基于拟合中线的智能车巡线方案V2

import cv2 as cv import os import numpy as np# 遍历文件夹函数 def getFileList(dir, Filelist, extNone):"""获取文件夹及其子文件夹中文件列表输入 dir&#xff1a;文件夹根目录输入 ext: 扩展名返回&#xff1a; 文件路径列表"""newDir d…

[ MySQL ] — 库和表的操作

目录 库的操作 创建数据库 语法&#xff1a; 使用&#xff1a; 字符集和校验规则 查看系统默认字符集以及校验规则 查看数据库支持的字符集 查看数据库支持的字符集校验规则 校验规则对数据库的影响 操纵数据库 查看数据库 显示创建语句 修改数据库 删除数据库 备…

【Linux】计算机网络套接字编写

文章目录 前言TCP协议和UDP协议网络字节序socket接口sockaddr结构1.创建套接字 cs2.绑定端口号 s3.监听socket s4.接受请求 s5.建立连接 c 地址转换函数字符串转in_addrin_addr转字符串 recvfrom和sendto 前言 上篇文章我们学习了计算机网络分层&#xff0c;了解了网络通信的本…

Vue3_对响应式对象解构赋值之后失去响应性——toRefs()

官网toRefs() :响应式 API&#xff1a;工具函数 | Vue.js toRefs 在调用时只会为源对象上可以枚举的属性创建 ref。如果要为可能还不存在的属性创建 ref&#xff0c;请改用 toRef。 setup(){const state reactive({name:"张三"age:14})const stateAsToRefs toRef…

保留网络:大型语言模型的Transformer继任者

原文信息 原文题目&#xff1a;《Retentive Network: A Successor to Transformer for Large Language Models》 原文引用&#xff1a;Sun Y, Dong L, Huang S, et al. Retentive Network: A Successor to Transformer for Large Language Models[J]. arXiv preprint arXiv:2…