Java 自定义注解 笔记总结(油管)

news2024/9/26 3:22:59

Java系列文章目录

IDEA使用指南

Java泛型总结(快速上手详解)

Java Lambda表达式总结(快速上手详解)

Java Optional容器总结(快速上手图解)

Java 自定义注解笔记总结(油管)

Java 抽象知识笔记总结(油管)

Java 抽象相关知识笔记


文章目录

  • Java系列文章目录
  • 一、前言
  • 二、学习内容:
  • 三、问题描述
  • 四、解决方案:
    • 4.1 自定义注解引入
    • 4.2 自定义注解使用
      • 4.2.1 自定义注解概念
      • 4.2.2 自定义注解内部的属性
  • 五、总结:
    • 5.1 学习总结:

一、前言

目的:学习自定义注解相关内容

  • 对油管博主John讲解的注解相关知识进行笔记总结

二、学习内容:

  • 自定义注解的使用

三、问题描述

  • 自定义注解没有实践经验

四、解决方案:

4.1 自定义注解引入

主要了解自定义注解如何创建以及如何使用

引入自定义注解的意义:

  • 增强可读性:使代码更清晰,便于理解。
  • 元编程:运行时动态获取注解信息,调整程序行为。
  • 减少重复代码:简化配置和逻辑,提升开发效率。
  • 框架集成:与框架(如Spring)自然结合,简化开发。
  • 参数验证:验证用户输入的合法性。
  • 文档生成:自动生成接口和文档。
  • 配置管理:结合逻辑与配置,便于维护。

参考代码如下:

package org.example;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        Cat mycat = new Cat("Kitty");
        Dog mydog = new Dog("Jerry");
        if (mydog.getClass().isAnnotationPresent(VeryImportant.class))
        {
            System.out.println("This is a very important dog!");
        } else {
            System.out.println("This is not a very important dog!");
        }

        for (Method method :mycat.getClass().getDeclaredMethods())
        {
            if (method.isAnnotationPresent(RunImmediately.class))
            {
                RunImmediately annotation = method.getAnnotation(RunImmediately.class);
                for (int i = 0; i < annotation.times(); i++) {
                    method.invoke(mycat);
                }
            }
        }

        for (Field declaredField : mycat.getClass().getDeclaredFields()) {
            if (declaredField.isAnnotationPresent(ImportantString.class))
            {
                Object value = declaredField.get(mycat);
                if (value instanceof String)
                {
                    System.out.println(value.toString().toUpperCase());
                }

            }
        }
    }
}
  • 将对这三个分别在类,方法与字段上的注解的使用方法进行讲解
package org.example;
@VeryImportant
public class Cat {
    @ImportantString
    String name;
    int age;
    public Cat(String name) {
        this.name = name;
    }
    @RunImmediately(times = 3)
    public void meow() {
        System.out.println("Meow");
    }

    public void eat() {
        System.out.println("Eating");
    }
}
@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME)
public @interface RunImmediately {
    int times();
}
@Target({ElementType.TYPE, ElementType.METHOD})
//实际运行时保留此注解,其他代码可以查看这个注释并在运行时通过反射使用他
//Source 开始编译代码前删除这个注释 处理警告
//CLASS 编译过程保留注释 运行时抛弃
@Retention(RetentionPolicy.RUNTIME)
public @interface VeryImportant {

}

Dog是参考类

在这里插入图片描述

  • 我们学习使用像下面这样的自定义注解

在这里插入图片描述

4.2 自定义注解使用

4.2.1 自定义注解概念

自定义注解在编程中主要用于提供额外的信息或元数据,它们并不直接参与程序的运行,而是供编译器、构建工具或其他处理程序在编译期间或运行时解析

使用场景:

  • 增强代码可读性:通过注解,开发者可以为特定代码块添加上下文相关的描述,帮助其他人更好地理解代码的功能。
  • 配置信息传递:在框架或库中,注解可以作为配置选项,用于指定组件的行为、路径或者其他需要动态设置的属性。
  • AOP(面向切面编程)支持:一些注解用于通知AOP框架进行切面的插入,比如@AspectJ注解。
  • 元数据收集:注解可以帮助系统收集关于代码结构、依赖关系等非功能性信息,便于分析、调试和性能优化。
  • 未来扩展:如果需要为现有代码预留扩展空间,自定义注解可以避免硬编码,方便后续修改。

主要学习下面两个元注解

@Target 定义注解作用的位置

  • ElementType.ANNOTATION_TYPE: 说明该注解只能应用于其他注解类型。
  • ElementType.FIELD: 用于字段(变量)上。
  • ElementType.METHOD: 用于方法上。
  • ElementType.PARAMETER: 用于方法参数上。
  • ElementType.CONSTRUCTOR: 用于构造函数上。
  • ElementType.TYPE: 用于类、接口或异常声明上。
  • ElementType.PACKAGE: 用于包上。
  • ElementType.LOCAL_VARIABLE: 用于局部变量上。
  • ElementType.MEMBER_CLASS: 用于成员内部类上。

@Retention 定义了注解应该在哪些级别保留其有效性

  • RUNTIME: 表示该注解在运行时仍然可见,并且可以通过反射API获取到。

  • SOURCE: 只在源代码级别有效,编译后会被丢弃。这种类型的注解通常用于编译器插件或生成其他源代码的时候。

  • CLASS: 仅在类加载时生效,在类加载完成并初始化后就不再可用。这意味着只有类文件级别的注解才会被保留。

在这里插入图片描述

  • 如果没有ElementType.METHOD就会报错

在这里插入图片描述

  • 观察结果

在这里插入图片描述

4.2.2 自定义注解内部的属性

  • 观察可知自定义注解里面参数是函数形式的

如果没有默认值则使用的时候必须写出

在这里插入图片描述

  • 同理关于字段的注解

在这里插入图片描述
在这里插入图片描述


五、总结:

5.1 学习总结:

  1. 注解的定义

自定义注解使用@interface关键字进行定义,并可以包含一些成员方法,通常用于定义额外的参数。

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

@Retention(RetentionPolicy.RUNTIME) // 指定注解的保留策略  
public @interface MyAnnotation {  
    String value() default ""; // 默认值  
    int number() default 0; // 另一个属性  
}  
  1. 注解的保留策略

RetentionPolicy.SOURCE:注解只会保留在源代码中,编译后会被丢弃。
RetentionPolicy.CLASS:注解会被保留在class文件中,但在运行时不可用。
RetentionPolicy.RUNTIME:注解会被保留在class文件中,在运行时可以通过反射读取。

  1. 注解的使用

可以将自定义注解应用于类、方法、字段、参数等。

@MyAnnotation(value = "example", number = 5)  
public class MyClass {  
    @MyAnnotation(value = "method")  
    public void myMethod() {  
    }  
}  
  1. 读取注解

可以通过Java反射机制读取注解的信息。

import java.lang.reflect.Method;  

public class AnnotationProcessor {  
    public static void main(String[] args) {  
        Class<MyClass> obj = MyClass.class;  

        // 读取类的注解  
        if (obj.isAnnotationPresent(MyAnnotation.class)) {  
            MyAnnotation annotation = obj.getAnnotation(MyAnnotation.class);  
            System.out.println("Class Annotation: " + annotation.value() + ", " + annotation.number());  
        }  

        // 读取方法的注解  
        try {  
            Method method = obj.getMethod("myMethod");  
            if (method.isAnnotationPresent(MyAnnotation.class)) {  
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);  
                System.out.println("Method Annotation: " + annotation.value());  
            }  
        } catch (NoSuchMethodException e) {  
            e.printStackTrace();  
        }  
    }  
}  
  1. 注解的元注解

在定义自定义注解时,可以使用元注解来指定注解的特性,常见的元注解有:

@Retention:指定注解的保留策略。
@Target:指定注解可以应用在什么地方(类、方法、字段等)。
@Documented:表明将注解包含在JavaDoc中。
@Inherited:允许子类继承超类的注解。

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

@Target(ElementType.METHOD) // 该注解只能用在方法上  
@Retention(RetentionPolicy.RUNTIME)  
public @interface MethodInfo {  
    String author() default "unknown";  
    String date();  
    int revision() default 1;  
}  
  1. 注解示例

以下是一个简单的自定义注解示例,展示了如何定义和应用注解:

@Target(ElementType.METHOD)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface Test {  
    String value() default "default test";  
}  
应用示例:

public class Example {  

    @Test(value = "This is a test method")  
    public void testMethod() {  
        System.out.println("Executing test method.");  
    }  
}  

(后续有遇到问题再添加)


声明:如本内容中存在错误或不准确之处,欢迎指正。转载时请注明原作者信息(麻辣香蝈蝈)。

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

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

相关文章

AI时代,我们还可以做什么?

最近看了本书&#xff0c;书名叫做《拐点&#xff1a;站在 AI 颠覆世界的前夜》&#xff0c;作者是万维钢。 本想着看完后&#xff0c;就能掌握一整套 AI 技巧&#xff0c;结果——竟然学了很多道理。 这本书讨论了以下话题&#xff1a; 我们该怎么理解这个 AI 大时代的哲学&am…

思迈特发布全新AI应用,Smartbi AIChat白泽来了

8月8日&#xff0c;Smartbi AIChat白泽新品发布会在云端与大家如期美好相约&#xff0c;共同见证思迈特软件基于AI Agent的新一代智能BI应用落地的全新里程碑时刻。 思迈特软件创始人吴华夫和产品总监杨礼显先后围绕商业智能行业发展趋势、产品demo show、技术原理及未来规划展…

Mysql,用户名重复,无法调用问题

问题描述&#xff1a; 我电脑的数据库用户名是&#xff0c;root。 因为经常需要帮别人封装程序&#xff0c;所以需要在我本机跑通别人的程序。有的程序里面也涉及到数据库&#xff0c;用户名也是&#xff0c;root&#xff0c;但是密码与我本机的不同。 之前我会修改我用户名…

【LVS】防火墙mark标记解决调度问题

实验环境是在之前部署DR模式集群的基础上做的&#xff0c;参考如下 部署DR模式集群 以http和https为例&#xff0c;当我们在webserver中同时开放80和443端口&#xff0c;那么默认控制是分开轮询的&#xff0c;就会出现了一个轮询错乱的问题&#xff1a; 当第一次访问80被轮询…

为什么要用数据库管理系统?5个你不得不知道的理由

你是否曾经想过,为什么几乎所有的企业和组织都在使用数据库管理系统(DBMS)?为什么不直接使用文件系统来存储和管理数据呢?如果你有这样的疑问,那么这篇文章正是为你而写。在接下来的内容中,我们将深入探讨使用数据库管理系统的5个关键原因,这些原因将彻底改变你对数据管理的认…

【Kubernetes】pod状态与故障排查

一、Pod启动阶段&#xff08;相位 phase&#xff09; pod创建完之后&#xff0c;一直到持久运行起来&#xff0c;中间有很多步骤&#xff0c;也就有很多出错的可能&#xff0c;因此会有很多不同的状态。 Pod的启动过程如下&#xff1a; 0&#xff09;controller-manager管理的…

qt-06QStackeddialog堆栈窗体应用

QStackeddialog堆栈窗体应用 QStackeddialog.hQStackeddialog.cppmain.cpp运行图 QStackeddialog.h #ifndef QSTACKEDDIALOG_H #define QSTACKEDDIALOG_H#include <QDialog> #include <QListWidget> #include <QStackedWidget> #include <QLabel>clas…

2024年【上海市安全员B证】模拟考试及上海市安全员B证证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 上海市安全员B证模拟考试参考答案及上海市安全员B证考试试题解析是安全生产模拟考试一点通题库老师及上海市安全员B证操作证已考过的学员汇总&#xff0c;相对有效帮助上海市安全员B证证考试学员顺利通过考试。 1、【…

PySide6||QPushButton的QSS样式

1、狗狗拜按钮 QQ202484-03338 (online-video-cutter.com) /* QPushButton的基本样式 */ QPushButton { background-image:url(:/xxx/第1帧.png); /* 设置背景图片 */ background-repeat: no-repeat; /* 不重复背景图片 */ background-position: center; /* 将背景图片居中…

PS网页版在线制作:云端设计让效率更上一层楼!

在当今的设计行业中&#xff0c;PS曾经被认为是不可替代的工具。然而&#xff0c;对于设计师&#xff0c;尤其是UI设计师来说&#xff0c;PS有点太复杂了。PS更新频率快&#xff0c;稳定性差&#xff0c;对计算机配置要求高。对于初学者来说&#xff0c;这显然是一个“负担”。…

简单Qt贪吃蛇项目

目录 先看效果 项目介绍 界面一&#xff1a;游戏大厅界面 界面二&#xff1a;关卡选择界面​编辑 界面三&#xff1a;游戏界面 游戏大厅页面 游戏关卡选择页面 游戏房间页面 封装贪吃蛇数据结构 初始化游戏房间界面 设置窗口大小、标题、图标等 蛇的移动 初始化贪…

TR3复现Tramsformer

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 Transformer模型是深度学习中的一个革命性架构&#xff0c;自从在NLP领域引入以来&#xff0c;就因其高效处理序列数据的能力而迅速成为主流。本文将通过…

谷粒商城实战笔记-nginx问题记录

记录在使用nginx中遇到的问题。 文章目录 1&#xff0c;网关路由匹配不生效2&#xff0c;网关路由配置前后顺序导致的问题(非nginx问题)3&#xff0c;nginx.conf upstream配置缺少端口4&#xff0c;配置结尾少分号5&#xff0c; proxy_pass 后跟的服务器 URL 是否以 / 结尾5.1 …

C语言学习:汉诺塔问题

汉诺塔_百度百科 (baidu.com)https://baike.baidu.com/item/%E6%B1%89%E8%AF%BA%E5%A1%94/3468295 // // Created by zzh on 2024/8/6. ////汉诺塔问题#include<stdio.h>void move(char x, char y) {printf("%c --> %c \n", x, y); }int hanoi(int count, i…

2024新版软件测试八股文及答案解析

前言 前面看到了一些面试题&#xff0c;总感觉会用得到&#xff0c;但是看一遍又记不住&#xff0c;所以我把面试题都整合在一起&#xff0c;都是来自各路大佬的分享&#xff0c;为了方便以后自己需要的时候刷一刷&#xff0c;不用再到处找题&#xff0c;今天把自己整理的这些…

WEB渗透未授权访问篇-Redis

测试 redis-cli redis-cli -h 127.0.0.1 flunshall 192.168.0.110:6379>ping PONG 存在未授权访问 JS打内网 var cmd new XMLHttpRequest(); cmd.open("POST", "http://127.0.0.1:6379"); cmd.send(flushall\r\n); var c…

51单片机之LED篇(二)独立按键

一、独立按键的介绍 1.1 独立按键的基本原理 相当于一种电子开关&#xff0c;按下时开关接通&#xff0c;松开时开关断开。 开关功能&#xff1a;独立按键内部通常包含一个有弹性的金属片&#xff0c;当按键被按下时&#xff0c;金属片与触点接触&#xff0c;电路连通&#x…

鸿蒙AI功能开发【hiai引擎框架-语音识别】 基础语音服务

hiai引擎框架-语音识别 介绍 本示例展示了使用hiai引擎框架提供的语音识别能力。 本示例展示了对一段音频流转换成文字的能力展示。 需要使用hiai引擎框架文本转语音接口kit.CoreSpeechKit.d.ts. 效果预览 使用说明&#xff1a; 在手机的主屏幕&#xff0c;点击”asrDemo…

CMake基础教程二

常用 环境变量 SET(ENV{VAR} VALUE)**常用变量&#xff1a;**| 变量名 | 含义 | | ----------------------------- | ---------------------------------------------------------…

Bitwise 首席投资官:忽略短期的市场波动,关注加密货币的发展前景

原文标题&#xff1a;《The Crypto Market Sell-Off: What Happened and Where We Go From Here》撰文&#xff1a;Matt Hougan&#xff0c;Bitwise 首席投资官编译&#xff1a;Chris&#xff0c;Techub News 加密货币市场在周末经历了大幅下跌。从上周五下午 4 点到周一早上 7…