注解(概念、分类、自定义注解)

注解基本概念

注解(元数据)为我们在代码中添加信息提供一种形式化的方法,我们可以在某个时刻非常方便的使用这些数据。将的通俗一点,就是为这个方法增加的说明或功能。

作用:

  1. 编写文档:通过代码里标识的注解生成文档【生成doc文档】
  2. 代码分析:通过代码里的标识的注解对代码进行分析【使用反射】
  3. 编译检查:通过代码里的标识的注解让编译器实现基本的编译检查

JDK提供的注解

Java目前内置了三种注解@Override、@Deprecated、@SuppressWarnnings

@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 {
}

@SuppressWarnnings:用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告(压抑警告)

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

元注解

Java提供了四种元注解,即修饰注解的注解。观察上面源码可以发现三种,即:@Target、@Retention、@Document、@Inherited。主要作用如下:

名称

作用

属性值

取值

@Target

标识该注解用于什么地方

ElementType

CONSTRUCTOR:构造器上声明

FILED:属性上声明

LOCAL_VARIABLE:局部变量上声明

METHOD:方法上声明

PACKAGE:包声明

TYPE:类、接口、enum上使用

@Retention

表示在注解保留的阶段

RetentionPolicy

SOURCE:注解在编译时丢掉

CLASS:注解在class文件中存在,但会被jvm丢弃

RUNTIME:jvm会保留注释,可以通过反射机制获取注解信息

@Document

描述注解是否被抽取到API文档

@Inherited

允许子类继承父类的注解

如何自定义注解

使用@interface定义注解,会自动继承java.lang.annotation.Annotation接口,类似于类自动继承Object一样。注解中的每个方法表示一个配置参数,返回类型即是参数类型,可以通过default标识参数默认值。

本质:就是一个接口默认继承java.lang.annotation.Annotation接口

定义方式如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)//十分重要
@Target(ElementType.METHOD)
public @interface Test {
String value() default "";
}

注解中的参数类型

注解中的参数只支持如下类型:

  • 所有的基本类型:byte、short、char、int、long、float、double
  • String类型
  • Class类型
  • enum类型
  • Annotation类型
  • 以上类型的数组

如果定义其他类型的参数编译器会报错。


 

使用注解的注意点

  • 如果注解只有一个参数,最好取名value,这样在使用的时候可以直接指定属性值。例如:@Test("hello")
  • 只能使用public和默认权限修饰符修饰参数
  • 参数默认值:注解参数必须有确定的值。要么在定义的时候给默认值;要么在使用注解的时候指定参数值。
  • 赋值时,如果只有一个属性,且属性名是value,则value可以省略,直接定义值即可。,数组赋值时,值用{ }包裹,但是数组只有一个值时,则{ }可以省略

注解处理器

如果没有读取注解的方法,那么该注解就没有任何意义。使用注解的过程中,注解处理器是必不可少的,Java反射机制,完成对注解的处理

注解处理器类库

Java通过反射机制获取类、方法、属性上的注解,因此java.lang.reflect提供AnnotationElement支持注解,主要方法如下:

boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判断该元素是否被annotationClass注解修饰
<T extends Annotation> T getAnnotation(Class<T> annotationClass):获取 该元素上annotationClass类型的注解,
如果没有返回null(//    其实就是在内存中生成一个该注释接口的子类实现对象)
Annotation[] getAnnotations():返回该元素上所有的注解
<T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass):返回该元素上指定类型所有的注解
Annotation[] getDeclaredAnnotations():返回直接修饰该元素的所有注解
<T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass):返回直接修饰该元素的所有注解

 

 总测试源码:每个分割是一个类

@Retention(RetentionPolicy.RUNTIME) //一定要加这个注解(注解的保留阶段)
public @interface WebServlet2 {public String value() default "";public String url() default "";public String name() default "";}/***************/
@WebServlet2(url = "/load3",name = "无语")
public class demo3 {void show(){System.out.println("我是demo3");}}/***************/
@WebServlet2(url = "/load")
public class demo2 {void show(){System.out.println("我是demo2");}
}/***************/
@WebServlet2(url = "/load")
public class demo1 {void show(){System.out.println("我是demo1");}}
/***************/package com.aqiuo.反射;import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class SumDemo {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {String arr[] =new String[]{"com.aqiuo.反射.demo1","com.aqiuo.反射.demo2","com.aqiuo.反射.demo3","com.aqiuo.反射.Person"};String urlname="/load";Class[] cls=new Class[arr.length];for (int i=0;i<arr.length;i++) {cls[i]=Class.forName(arr[i]);WebServlet2 annotation= (WebServlet2) cls[i].getDeclaredAnnotation(WebServlet2.class);if(annotation!=null) {String url = annotation.url();if (url.equals(urlname)) {System.out.println(arr[i]);Object x = cls[i].newInstance();Method method = cls[i].getDeclaredMethod("show");method.invoke(x);}}}}
}

 

小结:

  1. 以后大多数时候,我们会使用注解,而不是自定义注解
  2. 注解给谁看:
    1. 编译器
    2. 解析程序
  3. 注解不是程序的一部分

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

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

相关文章

S7-1200PLC和KEPserver OPC通信

KEPserver属于OPCserver商用软件,在国内的市场占有率还是比较高的,这篇博客介绍S71200PLC和KEPserver通信配置,首先我们看下我们的PLC的IP地址。 1、S7-1200PLC IP地址 接下来我们在KEPserver新建通道 2、新建通道 3、选择通道网卡 4、添加PLC IP地址 5、指定扫描模式 6、…

【用unity实现100个游戏之16】Unity中程序化生成的2D地牢4(附项目源码)

文章目录 最终效果前言素材按程序放置物品放置玩家和敌人控制主角移动参考源码完结 最终效果 前言 本期紧跟着上期内容&#xff0c;主要实现在地牢中生成物品、放置玩家和敌人。 素材 物品素材&#xff1a; https://itch.io/c/1597630/super-retro-world 按程序放置物品 …

基于Qt MP3音频播放器示例(可制作音频播放器)

​本次MP3文件也给出来,方便大家调试。话不多说直接上源码。 整个项目下载地址:CSDN:GetCode 昵称-》Qt魔术师:https://gitcode.com/m0_45463480/QtMP3/tree/main## .pro # 指定项目类型为应用程序。TEMPLATE = app# 指定项目的名称为musicplayerTARGET = musicplayer# 添…

民营五百强企业——利群集团的数字化转型升级实践:全集团统一办公,低代码构建应用

利群集团是一家跨地区、多业态、综合性的大型商业集团。多年来&#xff0c;利群集团在坚持以零售连锁和商业物流配送为主业的同时&#xff0c;积极同步发展多业态。在酒店连锁、药品物流和药店连锁、房地产开发、电子商务、文化投资、进出口贸易、跨境电商、金融、快递、矿泉水…

Unity中Shader变体优化

文章目录 前言一、在Unity中查看变体个数&#xff0c;以及有哪些变体二、若使用预定义的变体太多&#xff0c;我们只使用其中的几个变体&#xff0c;我们该怎么做优化一&#xff1a;可以直接定义需要的那个变体优化二&#xff1a;使用 skip_variants 剔除不需要的变体 三、变体…

乱序学机器学习——主成分分析法PCA

文章目录 概览PCA核心思想和原理PCA求解算法PCA算法代码实现降维任务代码实现PCA在数据降噪中的应用PCA在人脸识别中的应用主成分分析优缺点和适用条件优点缺点适用条件 概览 PCA核心思想和原理 PCA求解算法 特征向量表示分布的方向&#xff0c;特征值表示沿着个方向分布的程度…

什么是算法?

一、是什么 算法&#xff08;Algorithm&#xff09;是指解题方案的准确而完整的描述&#xff0c;是一系列解决问题的清晰指令&#xff0c;算法代表着用系统的方法描述解决问题的策略机制 也就是说&#xff0c;能够对一定规范的输入&#xff0c;在有限时间内获得所要求的输出 …

Day13 qt 高级控件,自定义控件,事件,绘图,定时器

高级控件 QListWidget 列表展示控件 效果 添加数据 ui->listWidget->addItem("A"); QStringList list; list << "B" << "C" << "D"; ui->listWidget->addItems(list); 设置item点击 void Widget::on_l…

【EI稳定检索】第三届绿色能源与电力系统国际学术会议(ICGEPS 2024)

第三届绿色能源与电力系统国际学术会议&#xff08;ICGEPS 2024&#xff09; 2024 3rd International Conference on Green Energy and Power Systems 绿色能源是指可以直接用于生产和生活的能源。它包括核能和“可再生能源”。随着世界各国能源需求的不断增长和环境保护意识…

uniapp小程序项目连接微信客服【最新/最全教程】

目录 文档微信官网文档图片微信小程序客服配置官网 效果图聊天地址手机微信电脑端 微信聊天功能实现微信小程序后台添加客服微信号以及配置代码实现参考最后 文档 微信官网文档 微信官网文档 图片 微信小程序客服配置官网 微信小程序客服配置官网 效果图 聊天地址 地址 手…

C++学习寄录(八.继承)

继承的语法&#xff1a;class 子类 : 继承方式 父类 class A : public B; A 类称为子类 或 派生类 B 类称为父类 或 基类 1.基本使用 未使用继承的代码比较冗余重复 #include <iostream> #include <fstream> #include <string> #include <chrono>…

Linux处理系统常见命令

目录 1 sudo 1.1 介绍 1.2 配合 2 ifconfig与ping 2.1 ifconfig 2.2 ping 3 kill 4 apt-get 4.1 介绍 4.2 配合 5 history 6 clear 7 env 1 sudo 1.1 介绍 给这条命令最高权限&#xff0c;比如 sudo cp something.txt /usr/bin/something.txt 1…

Visio学习笔记

1. 常用素材 1.1 立方体&#xff1a;张量, tensor 操作路径&#xff1a;更多形状 ⇒ 常规 ⇒ 基本形状 自动配色 在选择【填充】后Visio会自动进行配色&#xff1b;

【数据结构】——解决topk问题

前言&#xff1a;我们前面已经学习了小堆并且也实现了小堆&#xff0c;那么我们如果要从多个数据里选出最大的几个数据该怎么办呢&#xff0c;这节课我们就来解决这个问题。我们就用建小堆的方法来解决。 首先我们来看到这个方法的时间复杂度&#xff0c;我们先取前k个数据建立…

L1-004:计算摄氏温度

题目描述 给定一个华氏温度F&#xff0c;本题要求编写程序&#xff0c;计算对应的摄氏温度C。计算公式&#xff1a;C5(F−32)/9。题目保证输入与输出均在整型范围内。 输入格式&#xff1a;输入在一行中给出一个华氏温度。 输出格式&#xff1a;在一行中按照格式“Celsius C”…

接口中的大事务,该如何进行优化?

前言 作为后端开发的程序员&#xff0c;我们常常会的一些相对比较复杂的逻辑&#xff0c;比如我们需要给前端写一个调用的接口&#xff0c;这个接口需要进行相对比较复杂的业务逻辑操作&#xff0c;比如会进行&#xff0c;查询、远程接口或本地接口调用、更新、插入、计算等一…

解决msvcr71.dll丢失5个方法,修复程序运行缺失dll问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcr71.dll丢失”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;给使用者带来了很大的困扰。那么&#xff0c;究竟是什么原因导致了msvcr71.dll文件的丢失呢&#xff1f;本文…

什么是海外私人IP代理?是纯净独享的代理吗?

相信许多互联网工作者都遇到过IP禁令&#xff0c;比如网络抓取项目&#xff0c;使用共享代理服务器向网站发出第一个请求&#xff0c;但却您收到了禁令&#xff0c;这大部分是由于你的共享IP经过多人使用被禁用所致。 那么到底什么是私人代理呢&#xff1f;它们是否适合您的情…

微服务实战系列之Redis(cache)

前言 云淡天高&#xff0c;落木萧萧&#xff0c;一阵西北风掠过&#xff0c;似寒刀。冬天渐渐变得更名副其实了。“暖冬”的说法有点言过其实了。——碎碎念 微服务实战系列之Cache微服务实战系列之Nginx&#xff08;技巧篇&#xff09;微服务实战系列之Nginx微服务实战系列之F…

【VScode】代码文件注释,User snippets 配置 Python/C++ , 其他语言类似

在代码文件头部&#xff0c;输入 header &#xff0c;回车&#xff0c;自动生成文件注释 Python {"HEADER": {"prefix": "header","body": ["# -*- encoding: utf-8 -*-", "\"\"\"","Date …