00-JAVA基础-注解及反射解析注解

注解

什么是注解

Java 注解(Annotation)是 JDK 5.0 引入的一种元素,用于为 Java 代码提供元数据。元数据是关于数据的数据,它为代码提供附加信息,而这些信息并不直接参与到程序的逻辑中,但可以被编译器或其他工具使用。注解本身对代码的逻辑没有任何影响,但可以通过反射机制读取注解信息,从而执行相应的操作。

注解的作用

  • 不是程序本身,可以对程序作出解释
  • 可以被其他程序(如:编译器等)读取。注解可以通过反射对其进行解释处理,这个是注解与注释的最大区别。
    如果一个注解没有通过反射进行注解信息处理,那么这个注解毫无意义。

注解的格式

注解是以 “@注释名” 在代码中存在的,还可以添加一下参数值,例如:@SuppressWarnings({“unchecked”, “rawtypes”})

注解的使用范围

注解可以附加在package,class,method,field等上面,相当于给他们添加了额为的辅助信息,我们可以通过反射机制变成实现对这些元素的访问。

注解的分类

Java 注解可以分为以下三种类型:

  • 标记注解:没有任何属性的注解,如 @Override。
  • 单值注解:只有一个属性的注解,如 @Deprecated(“不建议使用”)。
  • 完整注解:包含多个属性的注解,如 @SuppressWarnings({“unchecked”, “rawtypes”})。

Java 的内置注解包括:

  • @Override:表示当前方法是重写了父类的方法。
  • @Deprecated:表示某个类或方法已经过时,不建议使用。
  • @SuppressWarnings:用于告诉编译器忽略指定的警告。

除了内置注解,Java 还允许开发者自定义注解。

如何自定义注解

使用@interface自定义注解是,自动继承了java.lang.annotation.Annotation接口

格式

public @interface 注解名{定义体}

示例:声明一个MyAnnotation注解,包含value(默认值 “”)、number(默认值 0)两个参数

public @interface MyAnnotation {  String value() default "";  int number() default 0;  
}

其中的每一个方法实际上是声明了一个配置参数。

  • 方法名称就是参数的名称
  • 返回值类型就是参数的类型(返回值类型只能是基本数据类型,Class,String,enum)
  • 可以通过default来声明参数的默认值
  • 如果只有一个参数成员,一般参数名为value

注意:

源代码中我们经常看见在注解上还有一些注解例如,以下示例:
其中@Target与@Retention称之为元注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

什么是元注解

元注解(Meta-Annotation)是用于定义其他注解的注解。在Java中,注解是一种为代码提供元数据的机制,而元注解则是对这些注解进行进一步描述的工具。JDK中定义了四种标准的元注解类型:@Target、@Retention、@Documented和@Inherited。

  • @Target:用于指定注解的作用目标,例如类、方法、字段等。
所修饰范围取值ElementType
packagePACKAGE
类、接口、枚举、Annotation类型TYPE
类型成员(方法、构造方法、成员变量、枚举)CONSTRUCTOR:用于描述构造器
FIELD:用于描述字段
METHOD:用于描述方法
方法参数和本地变量LOCAL_VARIABLE:用于描述局部变量
PARAMETER:用于描述参数
  • @Retention:表示需要在什么级别保存该注释信息,用于指定注解的生命周期,即注解在何时生效,包括SOURCE(源码时有效)、CLASS(编译时有效)和RUNTIME(运行时有效)三种。
取值RetentionPolicy作用
SOURCE在源文件中有效
CLASS在class文件中有效
RUNTIME在运行时有效,为Runtime可以被反射机制读取
  • @Documented:用于指定将该注解包含在javadoc中。
  • @Inherited:用于指定子类可以继承父类中的注解。

在自定义注解时,通常需要使用元注解来定义注解的属性、行为以及作用范围等。
通过元注解,开发者可以更加灵活地控制注解的使用和效果,从而实现更高级的功能。

元注解使用案例

使用@Target设置注解的作用目标是方法,则注解放在类上是就会报错.

MyAnnotation.java

package demo1;import java.lang.annotation.ElementType;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
public @interface MyAnnotation {
}

AnnotationDemo.java

package demo1;@MyAnnotation
public class AnnotationDemo {@MyAnnotationprivate void test(){}
}

编译结果:

在这里插入图片描述

反射机制读取注解

做一个简单User数据表与实体关系映射,通过反射解析创建生成表SQL

实体字段表字段备注
idint(10)主键
namevarchar2(30)-

表注解Table.java

package demo2.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 表名** @author Anna.* @date 2024/4/4 21:41*/
@Target(ElementType.TYPE)  // 设置作用范围
@Retention(RetentionPolicy.RUNTIME) // 设置生命周期
public @interface Table {String value();
}

主键Id.java

package demo2.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 主键注解** @author Anna.* @date 2024/4/4 21:38*/
@Target(ElementType.FIELD)  // 设置作用范围
@Retention(RetentionPolicy.RUNTIME) // 设置生命周期
public @interface Id {
}

字段注解Field.java

package demo2.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 字段** @author Anna.* @date 2024/4/4 21:42*/
@Target(ElementType.FIELD)  // 设置作用范围
@Retention(RetentionPolicy.RUNTIME) // 设置生命周期
public @interface Field {// 字段名称String columnName();// 类型String type();// 长度int length();
}

实体UserDo.java

package demo2;import demo2.annotation.Field;
import demo2.annotation.Id;
import demo2.annotation.Table;/*** |实体字段|表字段|备注|* |:---|:---|:---|* |id| int(10) | 主键 |* |name| varchar2(30) |-|** @author Anna.* @date 2024/4/4 21:36*/
@Table("USER_TABLE")
public class UserDo {@Id@Field(columnName = "id", type = "int", length = 10)private Integer id;@Field(columnName = "name", type = "varchar2", length = 30)private String name;public UserDo() {}public UserDo(Integer id, String name) {this.id = id;this.name = name;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "UserDo{" +"id=" + id +", name='" + name + '\'' +'}';}
}

测试案例AnnotationDemo.java

package demo2;import demo2.annotation.Id;
import demo2.annotation.Table;import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;/*** 反射模拟处理注解新** @author Anna.* @date 2024/4/4 21:35*/
public class AnnotationDemo {public static void main(String[] args) throws Exception {// 反射获取UserDoString path = AnnotationDemo.class.getClassLoader().getResource("").getPath();
//        System.out.println(path);Class<?> clazz = Class.forName("demo2.UserDo");// 初始化实例UserDo userDo = (UserDo) clazz.getDeclaredConstructor().newInstance();// 定义SQL 字段StringBuffer sb = new StringBuffer();sb.append("CREATE TABLE ");// 获取表注解Table table = clazz.getAnnotation(Table.class);sb.append(table.value()).append(" {");// 获取所有属性Field[] fields = clazz.getDeclaredFields();for (int i = 1; i <= fields.length; i++) {Field field = fields[i - 1];// 获取所有注解Annotation[] annotations = field.getAnnotations();String fieldStr = "";String idStr = "";for (Annotation a : annotations) {if (a instanceof demo2.annotation.Field) {demo2.annotation.Field a1 = (demo2.annotation.Field) a;fieldStr = a1.columnName() + " " + a1.type() + "(" + a1.length() + ")";} else if (a instanceof Id) {idStr = " PRIMARY";}}sb.append(fieldStr).append(idStr);if (i < fields.length) {sb.append(",");}}sb.append("}");System.out.printf("输出SQL:%s%n = ", sb.toString());}
}

执行结果:

在这里插入图片描述

gitee源码

git clone https://gitee.com/dchh/JavaStudyWorkSpaces.git

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

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

相关文章

Spring Boot | Spring Boot的“数据访问“、Spring Boot“整合MyBatis“

目录: 一、Spring Boot”数据访问概述“二、Spring Boot”整合MyBatis”1. 基础环境搭建 (引入对应的“依赖启动器” 配置数据库的“相关参数”)① 数据准备 (导入Sql文件)② 创建项目&#xff0c;引入相应的启动器&#xff0c;编写数据库对应的“实体类”③额外添加pom.xml文…

联想 Y9000P 连接网线速度慢 的 问题解决

参考帖子&#xff1a;求助&#xff0c;拯救者Y9000P 2022 i73060版本 有线网非常慢 无线网正常【笔记本吧】_百度贴吧 问题原因&#xff1a; 网卡驱动版本不对。不能用Win11版&#xff0c;要用Win10版。 问题解决&#xff1a; 1、卸载原驱动 2、下载Win10 驱动 并安装 下载…

MFC通用静态库制作与使用

开发环境VS2013 1、新建工程&#xff0c;选择Win32 Project&#xff0c;命名&#xff0c;选择路径等 2、选择Static library &#xff0c;勾选MFC 3、点击完成。在工程中添加相应的头文件、源文件等通用功能函数或者类。 4、在其他工程引入使用。在使用的工程项目设置中Linker…

tsv、csv、xls等文件类型区别及处理(python版)

目录 前言 介绍 tsv、csv、txt的区别 读取/生成 不同格式数据文件&#xff08;python&#xff09; 一、读取/生成csv数据文件 二、读取/生成txt数据文件 三、读取/生成tsv数据文件 四、读取/生成xls数据文件 不同文件格式转化 总结 前言 考虑到进行机器学习、深度学习…

vue快速入门(五)v-show与v-if

注释很详细&#xff0c;直接上代码 上一篇 新增内容 v-if与v-show底层的区别v-if与v-show的效果 源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice…

删除中间节点(狸猫换太子法)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 每一个裂缝都是为透出光而努力&#…

C++模板基础1——定义函数模板

函数模板定义格式 模板函数定义格式如下&#xff1a; template <typename T> 返回类型 函数名(参数列表) {// 函数体 }其中&#xff0c;template<typename T>是模板声明&#xff0c;用于定义模板参数 T。可以使用不同的关键字代替 typename&#xff0c;例如 clas…

腾讯云4核8G服务器最多能承载多少用户在线?谁知道?

腾讯云4核8G服务器价格&#xff1a;轻量4核8G12M优惠价格646元15个月、CVM S5服务器4核8G配置1437元买1年送3个月。腾讯云4核8G服务器支持多少人同时在线&#xff1f;支持30个并发数&#xff0c;可容纳日均1万IP人数访问。腾讯云百科txybk.com整理4核8G服务器支持多少人同时在线…

RabbitMQ Tutorial

参考API : Overview (RabbitMQ Java Client 5.20.0 API) 参考文档: RabbitMQ: One broker to queue them all | RabbitMQ 目录 结构 Hello World consumer producer 创建连接API解析 创建连接工厂 生产者生产消息 消费者消费消息 队列声明 工作队列Work Queues 公平…

Day81:服务攻防-开发框架安全SpringBootStruts2LaravelThinkPHPCVE复现

目录 PHP-框架安全-Thinkphp&Laravel Laravel CVE-2021-3129 RCE Thinkphp 版本3.X RCE-6.X RCE 版本6.X lang RCE J2EE-框架安全-SpringBoot&Struts2 Struct2 旧漏洞(CVE-2016-0785等) struts2 代码执行 &#xff08;CVE-2020-17530&#xff09;s2-061 Str…

LeetCode-437. 路径总和 III【树 深度优先搜索 二叉树】

LeetCode-437. 路径总和 III【树 深度优先搜索 二叉树】 题目描述&#xff1a;解题思路一&#xff1a;深度优先搜索解题思路二&#xff1a;0解题思路三&#xff1a;0 题目描述&#xff1a; 给定一个二叉树的根节点 root &#xff0c;和一个整数 targetSum &#xff0c;求该二叉…

刷题之Leetcode35题(超级详细)

35.搜索插入位置 力扣题目链接(opens new window)https://leetcode.cn/problems/search-insert-position/ 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 你可…

基于SSM实现的移动OA办公系统

系统介绍 基于SSM实现的移动OA办公系统设计了管理员、团队负责人、普通员工、部门负责人、人事部经理等几种用户角色 系统实现了如下功能&#xff1a; 管理员管理&#xff1a;用户管理、角色管理、权限管理、团队管理等功能 客户管理&#xff1a;客户管理、客户类型管理、状…

C语言笔试题之求解X的平方根

求解X的平方根 一、实例要求 1、给定一个非负整数 x &#xff0c;计算并返回 x 的算术平方根 &#xff1b;2、由于返回类型是整数&#xff0c;结果只保留整数部分 &#xff0c;小数部分将被舍去&#xff1b;3、不允许使用任何内置指数函数、运算符&#xff1b; 二、实例分析…

python作业

1.找出10000以内能被5或6整除&#xff0c;但不能被两者同时整除的数(函数) 2.写一个方法&#xff0c;计算列表所有偶数下标元素的和(注意返回值) 3.根据完整的路径从路径中分离文件路径、文件名及扩展名。 4.根据标点符号对字符串进行分行 5.去掉字符串数组中每个字符串的空格 …

江协STM32:定时器定时中断和定时器定时闹钟

定时器中断 新建文件 按这个图来编写程序 第一步&#xff1a;RCC开启时钟&#xff0c;定时器到基准时钟和整个外设到工作时钟就会同时打开 第二步&#xff1a;选择时基单元的时钟源&#xff0c;对于定时中断选择内部时钟源 第三步&#xff1a;配置时基单元&#xff0c;ARR,P…

Golang Channel底层实现原理

1、本文讨论Channel的底层实现原理 首先&#xff0c;我们看Channel的结构体 简要介绍管道结构体中&#xff0c;几个关键字段 在Golang中&#xff0c;管道是分为有缓冲区的管道和无缓冲区的管道。 这里简单提一下&#xff0c;缓冲区大小为1的管道和无缓冲区的管道的区别&…

维基百科推广方法及注意事项解析-华媒舍

1. 维基百科 维基百科是一个自由而开放的在线百科全书&#xff0c;由志愿者共同创建和编辑。它是全球最大的百科全书&#xff0c;包含了广泛的主题和知识。作为一个公共平台&#xff0c;维基百科是广告和宣传的禁区&#xff0c;但它可以是一个有效的推广工具&#xff0c;帮助您…

ENSP华为防火墙WEB登录操作指南

ENSP华为防火墙WEB登录操作指南 华为防火墙登录WEB 1、华为防火墙配置&#xff1a;&#xff08;需要在互联接口下放通https和ping&#xff09; int g0/0/0 service-manage https permit service-manage ping permit 2、电脑需要配置虚拟网卡 3、虚拟网卡与云和防火墙配置的IP地…

【学习心得】Numpy学习指南或复习手册

本文是自己在学习Numpy过后总是遗忘的很快&#xff0c;反思后发现主要是两个原因&#xff1a; numpy的知识点很多&#xff0c;很杂乱。练习不足&#xff0c;学习过后一段时间不敲代码就会忘记。 针对这两个问题&#xff0c;我写了这篇文章。希望将numpy的知识点织成一张网&…