【Java】Java(四十九):注解及自定义注解

news2024/12/23 23:40:20

文章目录

  • 什么是注解?
  • 概述
  • 注解的作用
  • 自定义注解
    • 注解的定义格式
    • 带有属性的注解
  • 注解的使用
    • 注解的使用格式
  • 元注解
    • 元注解的作用:
    • 常用元注解:
  • 注解解析



在这里插入图片描述

什么是注解?

  • 注解(Annotation)也称为元数据,是一种代码级别的说明
  • 注解是JDK1.5版本引入的一个特性,和类、接口是在同一个层次
  • 注解可以声明在包、类、构造器、字段、方法、成员变量、局部变量、方法参数等的前面,用来对这些元素进行说明

注解:就是具有特殊含义的标记(注解是给机器阅读的)

概述

作用:对Java中类、方法、成员变量做标记,然后进行特殊处理,至于到底做何种处理由业务需求来决定。
注解就是在代码里添加一些特殊标志,这些标志可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行操作。

注解与注释不同,会影响程序的执行,而注释不会。

注解的作用

  1. 编译检查
  • @Override:用来修饰方法声明。
  • 用来告诉编译器该方法是重写父类中的方法,如果父类不存在该方法,则编译失败。

02_注解的作用-1599230063774-1603446034951.png

  1. 代码分析
  • 通过代码里标识的注解对代码进行分析
  • 框架的配置( 框架 = 代码 + 配置 )
    • 具体使用请关注框架课程的内容的学习(注解去配置数据)
  1. 生成帮助文档
  • @author:用来标识作者姓名
  • @version:用于标识对象的版本号,适用范围:文件、类、方法
    • 使用@author和@version注解就是告诉Javadoc工具在生成帮助文档时把作者姓名和版本号也标记在文档中

01_注解的作用-1599230063773-1603446034951.png

使用过的注解

  • @Override
    • 用来修饰方法声明,告诉编译器该方法是重写父类中的方法,如果父类不存在该方法,则编译失败
  • @Test
    • Junit测试注解
  • @FunctionalInterface //函数式接口

自定义注解

注解的定义格式

定义注解使用关键字:@interface

public @interface 注解名{
   //内容
}

注解本质上就是一个接口。所有注解都会继承一个接口:Annotation

public interface 自定义注解名 extends java.lang.annotation.Annotation {}

带有属性的注解

  1. 属性的格式
  • 格式1:数据类型 属性名(); //无默认值的属性
  • 格式2:数据类型 属性名() default 默认值; //有默认值的属性
  1. 属性定义示例
public @interface Student {
  String name();                // 姓名
  int age() default 18;         // 年龄
  String gender() default "男"; // 性别
} 
// 该注解就有了三个属性:name,age,gender
  1. 属性适用的数据类型【记住】
  • 八种基本数据类型(int,short,long,double,byte,char,boolean,float)
  • String,Class,注解类型,枚举类
  • 以上类型的一维数组形式

注解的使用

注解的使用格式

//无属性注解
@注解名   例:@Test

//有属性注解
@注解名(属性=,属性=)

注解可以在类上,成员变量上,构造方法上,方法上,参数上…
有默认值的属性,可以不用进行赋值。

案例:

public @interface Book {
    String name();

    double price() default 100.0;

    String[] author();
}

建立一个BookStore的类,在类中定义成员变量,构造方法,成员方法

@Book(name = "西游记", author = {"吴承恩", "张三"})
public class BookStore {
    @Book(name = "三国", price = 10, author = {"罗贯中"})
    private String book;

    @Book(name = "三国", price = 10, author = {"罗贯中"})
    public BookStore() {
    }

    @Book(name = "三国", price = 10, author = {"罗贯中"})
    public void test() {

    }
}

如果注解中只有一个属性要赋值,而且名字是value,可以将value给省略,可以直接给值。

元注解

元注解的作用:

默认情况下,注解可以用在任何地方,比如类,成员方法,构造方法,成员变量等地方
如果要限制自定义注解的使用位置怎么办?那就要学习一个新的知识点:元注解
结论:元注解是用来约束自定义注解的使用范围、生命周期。

常用元注解:

常用元注解:@Target、@Retention

@Target

  • 作用:指明此注解用在哪个位置,如果不写默认是任何地方都可以使用
  • @Target可选的参数值在枚举类ElemenetType中包括:
    • TYPE: 用在类,接口上
    • FIELD:用在成员变量上
    • METHOD: 用在方法上
    • PARAMETER:用在参数上
    • CONSTRUCTOR:用在构造方法上
    • LOCAL_VARIABLE:用在局部变量上
    • PACKAGE:包
    • ANNOTATION_TYPE:注解上

@Retention

  • 作用:定义该注解的生命周期(有效范围)。
  • @Retention可选的参数值在枚举类型RetentionPolicy中包括:
    • SOURCE:注解只存在于Java源代码中,编译生成的字节码文件中就不存在了
      • 使用场景:针对一些检查性的操作,比如:@Override ,就使用SOURCE注解
    • CLASS:注解存在于Java源代码、编译以后的字节码文件中,运行的时候内存中没有(默认值 )
      • 使用场景:在编译时进行一些预处理操作,比如:生成一些辅助代码,就用CLASS注解
    • RUNTIME:注解存在于Java源代码中、编译以后的字节码文件中、运行时内存中,程序可以通过反射获取该注解
      • 使用场景:要在运行时去动态获取注解信息,那只能用 RUNTIME 注解

图

元注解的使用:

@Target({ElementType.METHOD,ElementType.TYPE}) //元注解
@interface Stu{
    String name();
}

//类
@Stu(name="jack")  //成功
public class AnnotationDemo02 {
    // 成员变量
    @Stu(name = "lily")  // 编译失败
    private String gender;
    
    // 成员方法
    @Stu(name="rose")  //成功
    public void  test(){
    }
   
    // 构造方法
    @Stu(name="lucy") // 编译失败
    public AnnotationDemo02(){}
}

注解解析

获取注解数据的原理:
想要对注解中的数据进行解析,需要借助:AnnotatedElement 接口

  • Field,Method,Constructor,Class 等类都是实现了 AnnotatedElement 接口

AnnotatedElement 是一个接口,定义了解析注解的方法:

1. boolean isAnnotationPresent(Class<Annotation> annotationClass)   
   判断当前对象是否使用了指定的注解,如果使用了则返回true,否则false
   
   public class BookStore{
       
       @Book(name="书名")
       public void buy() // Method对象 判断该对象上是否使用了@Book注解
       {                 // boolean flag = Method对象.isAnnotationPresent(Book.class)
       }
   } 
    
  
2. T getAnnotation(Class<T> annotationClass) 
   根据注解类型获得对应注解对象
   //	获取注解的具体值见下面的综合案例
   // 获取对象上的自定义注解
   // Book bookAnno = Method对象.getAnnotation(Book.class); 
   //      bookAnno.属性   //获取注解中属性的值

Class,Constructor,Method,Field都会实现AnnotatedElement 接口

  • 解析类型上的注解:借助字节码对象(Class对象)
  • 解析构造方法上的注解:借助构造器对象(Constructor对象)
  • 解析方法上的注解:借助方法对象(Method对象)
  • 解析字段上的注解:借助字段对象(Field对象)

注解解析的步骤:(注解是书写在:类、方法、变量上)
1、利用反射技术获取注解作用的对象:类、方法、变量、构造方法
2、判断对象上是否有自定义注解存在
3、有:获取对象上的自定义注解
4、使用获取到的自定义注解对象,拿到注解中的属性值

注意:注解解析必须保证自定义注解生命周期在RUNTIME(程序运行中)

案例:

需求如下:

  1. 定义注解Book,要求如下:
    • 包含属性:String value() 书名
    • 包含属性:double price() 价格,默认值为 100
    • 包含属性:String[] authors() 多位作者
    • 限制注解使用的位置:类和成员方法上 【Target】
    • 指定注解的有效范围:RUNTIME 【Retention】
  2. 定义BookStore类,在类和成员方法上使用Book注解
  3. 定义TestAnnotation测试类获取Book注解上的数据
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE}) //使用范围:方法、类
@Retention(RetentionPolicy.RUNTIME) //保证注解在程序执行时有效(适用于注解解析)
public @interface Book {
    String value();
    double price() default 100;
    String[] authors();
}


//类
public class BookStore {
    @Book(value = "Java入门", authors = {"张老师", "毕老师"})
    public void buy() {
        System.out.println("购书.....");
    }
}

//对注解中的数据进行解析
public class TestBookStore {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //反射套路:1、Class  2、构造器   3、Method
        Class<BookStore> bookStoreClass = BookStore.class;

        //获取构造器
        Constructor<BookStore> con = bookStoreClass.getConstructor();
        BookStore bookStore = con.newInstance();//实例化对象

        //获取Method
        Method method = bookStoreClass.getMethod("buy");

        //解析注解的步骤
        if(method.isAnnotationPresent(Book.class)){
            //获取Method对象上的Book注解
            Book bookAnno = method.getAnnotation(Book.class);

            //获取注解上的数据
            String bookName = bookAnno.value();
            double bookPrice = bookAnno.price();
            String[] bookAuthors = bookAnno.authors();

            System.out.println("书名:"+bookName);
            System.out.println("价格:"+bookPrice);
            System.out.println("作者:"+ Arrays.toString(bookAuthors));
        }
    }
}

小结
注解解析的步骤:

  1. 利用反射技术获取相关的对象:类、构造器、方法、变量
  2. 使用方法getAnnotation,获取自定义注解对象
  3. 使用注解对象,分别获取注解中的属性值



在这里插入图片描述

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

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

相关文章

数据库管理-第八十期 Exadata to RAC(x86) ADG(20230605)

数据库管理 2023-06-05 第八十期 Exadata to RAC(x86) ADG1 环境2 搭建流程2.1配置静态监听-主库2.2配置静态监听-备库2.3配置本地命名-主备库2.4数据库配置-主库2.5生成参数文件和密码文件-主库2.6创建目录并上传密码文件-备库2.7添加数据库服务-备库2.8修改参数文件-备库2.9复…

超级智能的治理

原文链接&#xff1a;https://openai.com/blog/governance-of-superintelligence#SamAltman 作者丨Sam Altman&#xff0c;Greg Brockman&#xff0c;Ilya Sutskever 译者 | Ted Liu 审校 | LsssY 编辑丨肖钰雯 现在是开始思考超级智能治理的好时机--未来的人工智能系统甚至比通…

基于SpringBoot+vue的租房网站设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

Python中的Time和DateTime

Python在处理与时间相关的操作时有两个重要模块&#xff1a;time和datetime。在本文中&#xff0c;我们介绍这两个模块并为每个场景提供带有代码和输出的说明性示例。 time模块主要用于处理时间相关的操作&#xff0c;例如获取当前时间、时间的计算和格式化等。它提供了一些函数…

老胡的周刊(第093期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 dm-ticket[2] 大麦网自动购票, 支持 docker …

4、数据库:MySQL部署 - 系统部署系列文章

MySQL数据库在其它博文中有介绍&#xff0c;包括学习规划系列。今天就讲讲MySQL的部署事情。 一、先下载MySQL数据库&#xff1b; 到下面这个网址去下载数据库&#xff0c;这里下载的社区版&#xff1a; https://dev.mysql.com/downloads/installer/ 二、安装数据库&#xff1b…

读改变未来的九大算法笔记04_公钥加密

1. 加密的目的就是传输秘密 2. 分块密码&#xff08;Block Cipher&#xff09;的现代加密技术使用了相加把戏的变体 2.1. 加法得出的结果能用于统计分析&#xff0c;这意味着一些人能通过分析你的大量加密消息来得到密钥 2.2. 任何知道密钥的人都能用相反的步骤运行所有操作…

MathType7中文标准版数学公式编辑工具

MathType 是一款专业的数学公式编辑工具,提供交互式编辑器&#xff0c; 让你在编辑数学试卷、书籍、报刊、论文、幻灯演示等文档轻松输入各种复杂的数学公式和符号。当您准备坐下来撰写科学或技术论文&#xff0c;测试&#xff0c;幻灯片演示文稿或任何想要包括数学符号的地方时…

互联网野蛮生长,但金三银四好像消失了!

每次看到程序员字眼&#xff0c;就是秃头&#xff0c;肥胖&#xff0c;宅男、996&#xff0c;程序员&#xff0c;但是耐不住工资高啊&#xff01;但只有程序员才知道&#xff0c;干IT的&#xff0c;都有一个自己的程序员梦&#xff0c;梦想着能用 “代码改变世界”。 代码能不…

音视频实战开源项目学习第二期!

前言&#xff1a; 大家好&#xff0c;今天继续分享音视频开源学习第二期&#xff0c;在前面的一期里面&#xff0c;我已经给大家演示了如何去跑起这个开源项目&#xff0c;包括源码下载&#xff1b; 音视频实战开源项目学习第一期&#xff01; 今天继续来讲解这个开源项目。 不…

chatgpt赋能python:Python多行连一行:简便省事的代码优化方法

Python多行连一行&#xff1a;简便省事的代码优化方法 在Python编程中&#xff0c;经常会遇到多行代码的情况&#xff0c;这不仅降低了代码的可读性&#xff0c;也增加了调试的难度。为了解决这个问题&#xff0c;Python提供了多行连一行&#xff08;以反斜杠\结尾&#xff09…

Mocha AE:工具栏

Mocha AE 工具栏&#xff08;经典模式&#xff09;中的工具及视图选项。 保存 Save the project 保存项目 快捷键&#xff1a;Ctrl S 选取类工具 Pick Tool 选取工具 --Marquee Selection 矩形框选 --Lasso Selection 套索选取 Move inner and edge points 移动内部点和边缘…

YOLOv8 训练自己的数据集

本范例我们使用 ultralytics中的YOLOv8目标检测模型训练自己的数据集&#xff0c;从而能够检测气球。 #安装 !pip install -U ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple import ultralytics ultralytics.checks() 一&#xff0c;准备数据 公众号算法美食屋后…

JavaScript之DOM(九)

JavaScript之DOM 1、节点类型2、常用的属性与方法2.1、访问节点的常用方法2.2、增删改节点的常用方法2.3、class的常用方法2.4、css相关操作 DOM – Document Object Model (文档对象模型)&#xff0c;是 JS 操作 HTML 文档的接口&#xff0c;它最大的特点就是将文档表示为节点…

CloudQuery一体化数据库SQL操作安全管控平台

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; CloudQuery一体化数据库SQL操作安全管控平台 导读 CloudQuery作为业界领先的面向企业的数据库安全解决方案&#xff0c;CloudQuery致力于打造一站式安全可靠的数据操…

【C++】右值引用和移动语义

1.左值和右值 在C中&#xff0c;每个表达式或者是左值&#xff0c;或者是右值。 左值(lvalue)&#xff1a;可以出现在赋值表达式左侧的值&#xff0c;例如变量名a、数据成员a.m、下标表达式a[n]、解引用表达式*p等。左值可以被赋值和取地址。右值(rvalue)&#xff1a;只能出现…

jdk动态代理源码分析

jdk动态代理源码分析 前言动态代理----demo 案例jdk动态代理源码创建代理对象获取类把二进制流生成文件 jdk 动态代理的原理 前言 上一篇中我们知道动态代理的使用, Javase 专题之 静态代理和动态代理 我们只知道其中的使用,但是原理是什么? 不明白原理只知皮毛不是我们的目的…

chatgpt赋能python:Python在原图上继续画的SEO

Python在原图上继续画的SEO Python是一种高级的多范式编程语言&#xff0c;它使用简单、易于阅读的语法以及丰富和强大的数据结构使其成为工程师的首选。Python已经成为了一种非常流行的编程语言&#xff0c;它用于多种应用领域&#xff0c;包括Web开发、数据科学、机器学习、…

区间预测 | MATLAB实现基于QRCNN-LSTM卷积长短期记忆神经网络多变量时间序列区间预测

区间预测 | MATLAB实现基于QRCNN-LSTM卷积长短期记忆神经网络多变量时间序列区间预测 目录 区间预测 | MATLAB实现基于QRCNN-LSTM卷积长短期记忆神经网络多变量时间序列区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 1.Matlab实现基于QRCNN-LSTM卷积神经…

注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】

目录 一、注解配置AOP 1. 开启注解支持 2. 在类和方法加入注解 3. 测试 4. 为一个类下的所有方法统一配置切点 二、原生Spring实现AOP 1. 引入依赖 2. 编写SpringAOP通知类 3. 编写配置类bean2.xml 4 测试 三、SchemaBased实现AOP 1. 配置切面 2. 测试 往期专栏…