Java注解和自定义注解以及应用。

news2025/3/1 3:26:08
  • 😜           :是江迪呀
  • ✒️本文关键词微信小程序页面跳转移动端前端
  • ☀️每日   一言追求潮流,其本身一点都不潮流!

在这里插入图片描述

一、前言

使用 Java 注解(Annotations)可以在代码中添加元数据,提供了一种将元数据与代码关联的方式。注解可以在类、方法、字段等各种元素上使用,以提供附加的信息,这些信息可以被编译器、工具或者运行时使用。注解编程也是Java知识体系中很重要的一环。

二、什么是注解

在计算机编程中,注解(Annotation)是一种为代码添加元数据(metadata)的方式,用于提供关于代码的附加信息。注解可以用于类、方法、字段、参数等程序元素,以便在编译时、运行时或者使用特定工具时进行处理。注解是一种用于描述代码的元数据,它本身不会影响代码的逻辑运行,但可以为代码提供一些附加的信息。这些信息可以用于编译器的优化、代码分析、文档生成、测试等各种用途。

2.1 注解作用:

注解可以用来处理一些繁琐而具有共性的东西,比如日志添加、鉴权,可以有效的减少代码量、配置项从而提高代码的可读性、一致性。

2.2 注解分类

注解一般分为预定义注解自定义注解

(1)预定义注解:

Java中有很多预定义注解,比如:

  • @Override:标记方法覆盖父类方法。
  • @Deprecated:标记方法或类已过时,不推荐使用。
  • @SuppressWarnings:抑制编译器警告。
  • @FunctionalInterface:标记接口是一个函数式接口。
    等等……这些注解可以直接用于相应的情况。

(2)自定义注解:

Java 还支持自定义注解。自定义注解使用 @interface 关键字定义,并可以在注解内部定义元素。自定义注解可以带有默认值,也可以指定保留策略(源代码、类文件、运行时等)。

三、自定义注解

3.1 实现一个注解

如果你想要自定义一个注解是很简单的,如下代码所示:

public @interface MyAnnotation {
	// 定义一个属性名为 "value"
    String value() default ""; 
    // 定义一个属性名为 "count",并设置默认值
    int count() default 1; 
}

如果你想使用:

@MyAnnotation(value = "Hello", count = 3)
public class MyClass {
...
}

非常简单。

3.2 注解属性介绍

我们可以在自定义注解类上面加上元注解,那么有哪些元注解可以使用,他们的作用是什么?如下所示:

(1)@Retention:这个元注解指定了自定义注解的保留策略,即注解在什么级别保留。它有以下取值:

  • RetentionPolicy.SOURCE:注解仅保留在源代码中,编译后不包含在字节码中。
  • RetentionPolicy.CLASS:注解保留在字节码中,但不会在运行时被反射获取(默认值)。
  • RetentionPolicy.RUNTIME:注解保留在字节码中,并可以在运行时通过反射获取(实际场景中使用最多)。

(2)@Target: 这个元注解指定了自定义注解可以应用在哪些元素上,如果自定义的注解只能作用于方法上,那么就不能作用于类上。它有以下取值:

  • ElementType.TYPE:作用于类、接口、枚举等类型。 ElementType.FIELD:字段。
  • ElementType.METHOD:作用于方法。 ElementType.PARAMETER:方法参数。
  • ElementType.FIELD:作用于属性。
  • ElementType.PACKAGE:用于包声明。
  • ElementType.LOCAL_VARIABLE:用于局部变量。
  • ElementType.CONSTRUCTOR:作用于构造函数。 ElementType.LOCAL_VARIABLE:局部变量。
  • ElementType.ANNOTATION_TYP:作用于注解类型。 ElementType.PACKAGE:包。
  • ElementType.TYPE_PARAMETER:作用于类型参数(Java 8+)。
  • ElementType.TYPE_USE:作用于类型使用(Java 8+)。

(3)@Documented: 这个元注解用于指定自定义注解是否应该包含在Java文档中。如果一个注解被标记为 @Documented,则它会出现在生成的API文档中。
(4)@Inherited: 这个元注解用于指定自定义注解是否可以被继承。如果一个注解被标记为 @Inherited,则子类会继承父类上的相同注解。

四、使用场景

4.1 对方法添加文档

我们有一个简单的用户类,我们想要为其中的某些方法添加一些说明文档。我们可以使用自定义注解来实现这个目标。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodDocumentation {
    String value() default "";
}

import cn.trueland.anno.MethodDocumentation;
import lombok.Data;

@Data
public class User {
    private String userId;

    @MethodDocumentation("这个方法返回的是用户的姓名!")
    public String getName() {
        return "是江迪呀";
    }
}

在其他地方使用反射来获取注解的信息:

import cn.trueland.anno.MethodDocumentation;
import cn.trueland.model.User;

import java.lang.reflect.Method;

public class TestRunMain {
    public static void main(String[] args) {
        User user = new User();
        Method[] methods = user.getClass().getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(MethodDocumentation.class)) {
                MethodDocumentation annotation = method.getAnnotation(MethodDocumentation.class);
                System.out.println("Method: " + method.getName());
                System.out.println("Documentation: " + annotation.value());
                System.out.println();
            }
        }
    }

}

结果:

Method: getName
Documentation: 这个方法返回的是用户的姓名!

4.2 日志记录

如果单独使用自定义注解,能够实现的东西很少,但是如果加上AOP那么应用的场景就很多了。
下面是自定义注解 + AOP实现的一个记录日志的代码示例:
(1)日志实体类:

import lombok.Data;

@Data
public class Log {
    /**
     * 操作类型
     */
    private String operationType;
    /**
     * 操作内容
     */
    private String operationContent;
    /**
     * 操作人id
     */
    private Long userId;
    /**
     * 操作人名称
     */
    private String userName;
}

(2)自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogAnnotation {
    /**
     * 操作类型
     */
    String OperationType() default "";
    /**
     * 操作内容
     */
    String OperationContent() default "";
    /**
     * 操作人id
     */
    long UserId() default 0;
    /**
     * 操作人名称
     */
    String UserName() default "";
}

(3)将注解属性转为注解对象工具类:

public class AnnotationUtil {
    public static <T extends Annotation> T getAnnotationMessageClass(JoinPoint joinPoint, Class<T> tClass) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (null == method) {
            return null;
        }
        return method.getAnnotation(tClass);
    }
}

(4)AOP切面:

@Aspect
@Component
@Slf4j
public class LogAop {
    //切面的路径就是你自定义注解的路径
    @Pointcut("@annotation(cn.trueland.anno.LogAnnotation)")
    public void pointCut(){}

    //使用后置通知
    @After("pointCut()")
    public void beforeAop(JoinPoint joinPoint){
        //获取日志对象
        LogAnnotation logAnnotation = AnnotationUtil.getAnnotationMessageClass(joinPoint, LogAnnotation.class);
        //处理日志入库逻辑
        System.out.println("操作类型:" + logAnnotation.OperationType());
        System.out.println("操作内容:" +logAnnotation.OperationContent());
        System.out.println("操作人id:" +logAnnotation.UserId());
        System.out.println("操作用户名:" +logAnnotation.UserName());
    }
}

(5)具体的方法

@LogAnnotation(OperationType = "添加",OperationContent = "添加用户信息",UserId = 01,UserName="是江迪呀")
    public void add(){
        //业务逻辑
    }

(6)运行结果:

操作类型:添加
操作内容:添加用户信息
操作人id:1
操作用户名:是江迪呀

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

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

相关文章

读书笔记-10张不同的思维导图

用思维导图做的读书笔记 当我们阅读一本书时&#xff0c;需要整理和记录书中的关键信息和观点&#xff0c;如果用传统的笔记方法&#xff0c;不仅会信息凌乱&#xff0c;而且效率低下。思维导图可以帮助我们更好地理解和组织一本书中所读内容。 一、我们先来了解一下什么是思…

Stable Diffusion 系列教程 | 文生图 - 提示词

目录 1.提示词 基本的规则 2.提示词分类 2.1内容性提示词 2.2 画风艺术派提示词 2.3 画幅视角 2.4画质提示词 3 反向提示词 3.1 内容性反向提示词 3.2 画质性反向提示词 4 实例分析 5 权重 5.1 方法一 5.2 方法二 6.参数 7. 学习and 技巧 7.1 辅助写提示词的网…

c++ 虚函数类对象模型

一、复杂的菱形继承及菱形虚拟继承 单继承&#xff1a;一个子类只有一个直接父类时称这个继承关系为单继承。 多继承&#xff1a;一个子类有两个或以上直接父类时称这个继承关系为多继承。 菱形继承&#xff1a;菱形继承是多继承的一种特殊情况。 菱形继承的问题&#xff1a;从…

从零开始学习YOLOv5 保姆级教程

一、前言 YOLO系列是one-stage且是基于深度学习的回归方法&#xff0c;而R-CNN、Fast-RCNN、Faster-RCNN等是two-stage且是基于深度学习的分类方法。 YOLOv5是一种单阶段目标检测算法&#xff0c;该算法在YOLOv4的基础上添加了一些新的改进思路&#xff0c;使其速度与精度都得…

【C++】vector类的模拟实现(SGI版本)

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;C的学习之路 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录 前言一、vector类的模拟实现1.1 vect…

SpringCloud Alibaba实战和源码(7)Skywalking

什么是SkyWalking Skywalking是由国内开源爱好者吴晟开源并提交到Apache孵化器的产品&#xff0c;它同时吸收了Zipkin /Pinpoint /CAT 的设计思路。特点是&#xff1a;支持多种插件&#xff0c;UI功能较强&#xff0c;支持非侵入式埋点。目前使用厂商最多&#xff0c;版本更新较…

水溶性焊锡丝非水溶焊锡丝

Sn63Pb37&#xff0c;无FLUX&#xff0c;水清洗&#xff1b;A可理解为余量或者国标A类标准1% Sn63Pb37&#xff0c;FLUX 1.8% 焊锡膏 焊锡丝 焊锡丝&#xff0c;英文名称&#xff1a;solder wire&#xff0c;由锡合金和助剂两部分组成&#xff0c;合金成份分为锡铅、无铅助剂均…

PX4使用esp8266

文章目录 前言一、给esp8266下载固件接线下固件 二、配置esp8266 前言 硬件&#xff1a; esp01s(esp01好像有些问题&#xff0c;不建议用) usb转串口模块 pix飞控 软件&#xff1a; qgc PX4 参考&#xff1a; https://docs.px4.io/main/en/telemetry/esp8266_wifi_module.html…

1.4亿X区城市运行“一网统管”体系建设项目项目招标WORD

导读&#xff1a;原文《1.4亿X区城市运行“一网统管”体系建设项目项目招标WORD》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 部分内容&#xff1a; 各部分需求…

VS code 设置 资源管理器 对齐线

点击左上角的File --> Preformences --> Settings 然后搜索 workbench&#xff0c;把workbench.tree.renderIndentGuides选成always&#xff0c;这样会一直显示对齐的竖线。 找到workbench.tree.indent&#xff0c;这个值就是缩进的像素数量&#xff0c;值越大&#xff0…

electron+vue3全家桶+vite项目搭建【16.1】electron多窗口,pinia状态同步,扩展store方法,主动同步pinia的状态【推荐】

文章目录 引入实现效果如下实现步骤1.自定义pinia插件2.主进程补充同步处理 引入 demo项目地址 我们之前写了一个自动同步pinia状态的插件&#xff0c;可以参考如下文章 electronvue3全家桶vite项目搭建【16】electron多窗口&#xff0c;pinia状态无法同步更新问题解决 这里…

WinPlan经营大脑:专注企业经营分析预测的垂直大模型

目录 一、WinPlan的核心功能与优势 二、WinPlan的应用场景与案例 三、数利得的团队与未来发展 四、投资方观点 随着科技的不断进步和市场竞争的日益激烈,企业数字化转型已成为提高经营效率和管理水平的关键。然而,许多企业在经营决策过程中仍面临许多问题,尤其在管理层的…

2023年国赛 高教社杯数学建模思路 - 案例:随机森林

文章目录 1 什么是随机森林&#xff1f;2 随机深林构造流程3 随机森林的优缺点3.1 优点3.2 缺点 4 随机深林算法实现 建模资料 ## 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是随机森林&#xff…

免费开源大型商城系统_支持商用_无需授权_OctShop

一、OctShop免费开源大型商城系统&#xff0c;支持商用 OctShop是一个免费开源的大型商城系统&#xff0c;无需官方授权就可以直接商用&#xff0c;商城系统集B2B2C和O2O模式于一体。采用前后端分离 八大数据库 分布式系统 微服务架构&#xff0c;支持高并发&#xff0c;非…

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)

[ 3.405676] No filesystem could mount root, tried: squashfs [ 3.411546] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)可能的原因之一&#xff1a; uboot中rootfs分配的大小不够 解决&#xff1a; 修改root到一个合适的大小…

基于启扬RK3399核心板消防控制图形显示装置的解决方案

在我们日常生活中&#xff0c;火灾的发生是不可避免的风险之一&#xff0c;为了能及时发现火灾&#xff0c;并能够迅速采取措施进行灭火和救援&#xff0c;消防系统起着至关重要的作用。而在消防系统中&#xff0c;消防控制室图形显示装置是其中的重要组成部分之一。 消防控制图…

javaScript:七夕特辑-对象的认识与应用(包含日期对象及相关案例)

目录 一.前言 二.认识对象 在js中声明对象的方法 1.直接使用{}声明对象 2.使用构造函数创建对象 获取属性的值 执行对象方法 解释 三.对象的应用 代码 效果图 ​编辑 四.日期对象 1.Date 日期对象 2. getFullYear() 获取当前年份 3.getMonth() 获取当前日期对象…

ethers.js2:provider提供商

1、Provider类 Provider类是对以太坊网络连接的抽象&#xff0c;为标准以太坊节点功能提供简洁、一致的接口。在ethers中&#xff0c;Provider不接触用户私钥&#xff0c;只能读取链上信息&#xff0c;不能写入&#xff0c;这一点比web3.js要安全。 除了之前介绍的默认提供者d…

DataSecurity Plus:守护企业数据安全的坚实屏障

在数字化时代&#xff0c;数据被誉为企业最重要的资产之一。然而&#xff0c;随着大数据的兴起和信息的日益增长&#xff0c;企业面临着前所未有的数据安全挑战。为了应对这些挑战&#xff0c;数据安全管理变得至关重要。在这个领域&#xff0c;ManageEngine的DataSecurity Plu…

TCP滑动窗口

为什么会有滑动窗口 在计算机网络中&#xff0c;数据通常被分成小块&#xff08;也叫数据段&#xff09;在网络中传输&#xff08;为什么会被分成小块&#xff0c;请了解拥塞窗口和流量控制&#xff09;。这些小块可能会在传输的过程中遇到延迟、丢失或乱序等问题。为了保证数据…