当前位置: 首页 > news >正文

Java:反射、注解

文章目录

  • 1. 反射
    • 1-1. 获取Class对象的三种方式
    • 1-2. 获取类的构造器、实例化对象
    • 1-3. 获取类的成员变量
    • 1-4. 获取类的成员方法
  • 2. 注解
    • 2-1. 元注解
    • 2-2. 解析注解

1. 反射

反射:加载类,并允许以编程的方式解剖类中的各种成员变量、方法、构造器。

1-1. 获取Class对象的三种方式

  1. Class c = 类名.class
  2. 调用Class提供方法:forName(String package),需要提供Java类的文件路径
  3. Object提供的方法:Class c = 对象.getClass()
package Java_fs;class User{}public class JavaFs1 {public static void main(String[] args) throws ClassNotFoundException {Class c = User.class;System.out.println(c.getName());System.out.println(c.getSimpleName());System.out.println("**************************");Class c1 = Class.forName("Java_fs.User");System.out.println(c1 == c);System.out.println("**************************");User user = new User();Class c2 = user.getClass();System.out.println(c2 == c);}
}

在这里插入图片描述

1-2. 获取类的构造器、实例化对象

推荐使用类对象.getDeclaredXXX这种方式来获取,这样可以获取所有的构造器,而不是仅仅得到被public修饰的构造器。
在这里插入图片描述

package Java_fs;import java.lang.reflect.Constructor;class User2{private String name;private Integer age;public User2() {}private User2(String name){this.name = name;}public User2(String name, Integer age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "User2{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class JavaFs2 {public static void main(String[] args) throws NoSuchMethodException {Class c1 = User2.class;System.out.println("获取被public修饰的构造器");Constructor[] constructors = c1.getConstructors();// 只能获取被public修饰的构造器for (Constructor constructor : constructors) {System.out.println("构造器名为:"+constructor.getName());// 获取构造器的名称System.out.println("参数个数为:"+constructor.getParameterCount());// 构造器的参数个数}System.out.println("获取所有的构造器");// 获取所有的构造器Constructor[] constructors2 = c1.getDeclaredConstructors();// 只能获取被public修饰的构造器for (Constructor constructor : constructors2) {System.out.println("构造器名为:"+constructor.getName());// 获取构造器的名称System.out.println("参数个数为:"+constructor.getParameterCount());// 构造器的参数个数}System.out.println("获取指定的构造器。。。。有参数的");Constructor constructor = c1.getDeclaredConstructor(String.class,Integer.class);System.out.println("构造器名为:"+constructor.getName()+"参数个数为:"+constructor.getParameterCount());}
}

在这里插入图片描述
如果想通过这个构造器对象进行实例化,可以直接.newInstance(参数)即可,但是需要某个构造器是私有的,那还是会报错,如下:

package Java_fs;import java.lang.reflect.Constructor;class User2{private String name;private Integer age;public User2() {}private User2(String name){this.name = name;}public User2(String name, Integer age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "User2{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class JavaFs2 {public static void main(String[] args) throws Exception{Class c1 = User2.class;System.out.println("获取指定的构造器。。。。有参数的");Constructor constructor = c1.getDeclaredConstructor(String.class,Integer.class);System.out.println("构造器名为:"+constructor.getName()+"参数个数为:"+constructor.getParameterCount());User2 user = (User2) constructor.newInstance("张三", 20);System.out.println(user);Constructor constructor1 = c1.getDeclaredConstructor(String.class);// constructor1.setAccessible(true);// 禁止检查访问权限User2 user2 = (User2) constructor1.newInstance("张三");System.out.println(user2);}
}

在这里插入图片描述
在这里插入图片描述
这是因为这个一个参数的构造器是被private修饰的,此时如果想强行获取到,可以在构造器下方设置权限,如下::
在这里插入图片描述

1-3. 获取类的成员变量

推荐使用getDeclaredField这种方式来获取,这样所有的都可以获取到。
在这里插入图片描述

package Java_fs;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;class User2{private static int a;private static final String COUNTRY = "China";private String name;public Integer age;@Overridepublic String toString() {return "User2{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class JavaFs2 {public static void main(String[] args) throws Exception{Class c1 = User2.class;Field[] fields = c1.getDeclaredFields();for (Field field : fields) {System.out.println(field);}}
}

在这里插入图片描述
如果想获取指定的成员变量,只需要输入成员变量名即可。如果成员变量被private进行修饰,你想获取成员变量的值或者设置成员变量的值,那么需要设置禁止检查访问权限才行,否则会报错。

package Java_fs;import java.lang.reflect.Field;class User2{private static int a;private static final String COUNTRY = "China";private String name;public Integer age;@Overridepublic String toString() {return "User2{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class JavaFs2 {public static void main(String[] args) throws Exception{Class c1 = User2.class;Field country = c1.getDeclaredField("COUNTRY");country.setAccessible(true);// 设置禁止检查权限User2 user = new User2();String country1 = (String) country.get(user);System.out.println(country1);// 获取成员变量的值Field name = c1.getDeclaredField("name");name.setAccessible(true);name.set(user,"张三");System.out.println(user);}
}

在这里插入图片描述

1-4. 获取类的成员方法

推荐使用getDeclaredXXX这种方式来获取成员方法。
在这里插入图片描述
如果想执行方法对象对应的方法,需要方法对象.invoke(某对象,参数)即可执行对应类下的方法。

package Java_fs;import java.lang.reflect.Field;
import java.lang.reflect.Method;class User2{private static int a;private static final String COUNTRY = "China";private String name;public Integer age;public void setName(String name){this.name = name;}private void happy(String name){System.out.println(name+"哈哈");}private void eat(){System.out.println("吃饭。。");}@Overridepublic String toString() {return "User2{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class JavaFs2 {public static void main(String[] args) throws Exception{Class c1 = User2.class;Method[] methods = c1.getDeclaredMethods();// 获取所有的成员方法for (Method method : methods) {System.out.println(method.getName());}User2 user2 = new User2();Method eat = c1.getDeclaredMethod("eat");eat.setAccessible(true);// 设置禁止检查访问权限eat.invoke(user2);// 运行eat方法Method happy = c1.getDeclaredMethod("happy",String.class);happy.setAccessible(true);// 设置禁止检查访问权限happy.invoke(user2,"张三");// 运行happy方法}
}

在这里插入图片描述

2. 注解

就是Java代码里的特殊标记,让其他程序根据注解信息来决定怎样执行该程序。注解本质是一个接口,Java中所有的注解都是继承Annotation接口的,@xxx注解(…)其实就是一个实现类,实现了该注解以及Annotation接口。

package zj;@interface ZJOne {int a();String b();boolean c() default true;
}
package zj;@ZJOne(a=12,b="23",c=false)
public class ZjStudy {@ZJOne(a=12,b="23")public void test(){}public static void main(String[] args) {}
}

2-1. 元注解

用于修饰注解的注解。有两个,分别为@Target、@Retention。其中@Target用于声明被修饰的注解只能在哪些位置上使用。
在这里插入图片描述
@Retention用于声明注解的保留周期
在这里插入图片描述

2-2. 解析注解

package zj;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.TYPE,ElementType.METHOD})
// 应用在类和方法上面
@Retention(RetentionPolicy.RUNTIME)
@interface ZJOne {int a();String b();boolean c() default true;
}
package zj;import java.lang.annotation.Annotation;
import java.lang.reflect.Method;@ZJOne(a=12,b="23",c=false)
class Demo{@ZJOne(a=21,b="嘻嘻哈哈")public void print(){}
}public class ZjStudy {public static void main(String[] args) throws Exception {Class c = Demo.class;ZJOne zjOne = (ZJOne) c.getDeclaredAnnotation(ZJOne.class);System.out.println(zjOne.a());System.out.println(zjOne.b());System.out.println(zjOne.c());// 获取在类上的注解数据Method print = c.getDeclaredMethod("print");ZJOne zjOne1 = print.getDeclaredAnnotation(ZJOne.class);System.out.println(zjOne1.a());System.out.println(zjOne1.b());System.out.println(zjOne1.c());// 获取方法上注解数据}
}

在这里插入图片描述

相关文章:

Java:反射、注解

文章目录 1. 反射1-1. 获取Class对象的三种方式1-2. 获取类的构造器、实例化对象1-3. 获取类的成员变量1-4. 获取类的成员方法 2. 注解2-1. 元注解2-2. 解析注解 1. 反射 反射:加载类,并允许以编程的方式解剖类中的各种成员变量、方法、构造器。 1-1. …...

Java 通过枚举类减少if else

目录 一. 案例1二. 案例2三. 案例3四. 案例4 枚举类聚合封装消息 一. 案例1 涉及到EnumMap的实际使用 ⏹定义一个枚举类,用来表示日本的各种支付方法对应的code import com.fasterxml.jackson.annotation.JsonFormat;// 让jackson将前台的数据封装数据到枚举类中 J…...

单链表---移除链表元素

对于无头单向不循环链表,给出头结点head与数值val,删除链表中数据值val的所有结点 #define ListNodeDataType val struct ListNode { struct ListNode* psll;ListNodeDataType val; } 方法一---遍历删除 移除所有数值为val的链表结点,…...

认识redis 及 Ubuntu安装redis

文章目录 一. redis概念二. redis应用场景二. redis的特性四. 使用Ubuntu安装redis 一. redis概念 redis 是在内存中存储数据的中间件, 用在分布式系统 redis是客户端服务器结构的程序, 客户端服务器之间通过网络来通信 二. redis应用场景 redis可用作数据库 类似MySQL, 但…...

Java开发网络安全常见问题

1、敏感信息明文传输 用户敏感信息如手机号、银行卡号、验证码等涉及个人隐私的敏感信息不通过任何加密直接明文传输。 如下图中小红书APP 的手机短信验证码登录接口,此处没有对用户手机号和验证码等信息进行加密传输,可以很简单的截取并开展一些合法的…...

C#基础之委托,事件

文章目录 1 委托1.1 简介1.2 操作使用1.2.1 声明委托(Delegate)1.2.2 实例化委托(Delegate)1.2.3 直接调用和invoke1.2.4 Invoke 和 BeginInvoke 1.3 委托的多播1.4 委托的匿名和lambda1.4.1 匿名方法1.4.2 lambda 表达式 1.5 内置…...

nginx配置静态资源的访问

比如静态资源图片位于/mnt/software/nginx/html/static/images目录下,那么nginx.conf中的配置则为: # 静态文件目录 location /static/images/ { root /mnt/software/nginx/html; try_files $uri $uri/ 404; #找不到时提示404 …...

JS的魔法三角:constructor、prototype与__proto__

在JavaScript中,constructor、prototype和__proto__是与对象创建和继承机制紧密相关的三个概念。理解它们之间的关系对于掌握JavaScript的面向对象编程至关重要。下面将详细介绍这个魔法三角: 1. constructor 定义:constructor是一个函数&am…...

CA系统(file.h---申请认证的处理)

#pragma once #ifndef FILEMANAGER_H #define FILEMANAGER_H #include <string> namespace F_ile {// 读取文件&#xff0c;返回文件内容bool readFilename(const std::string& filePath);bool readFilePubilcpath(const std::string& filePath);bool getNameFro…...

matlab显示sin二维图

1&#xff0c;新建脚本 2、保存脚本 3、脚本命令&#xff1a;clc 清除 脚本命令的信息 clrear all 清除全部 4工作区内容&#xff1a;变量啥的 x0:0.001:2*pi%% 开始 精度 中值 ysin(x) y1cos(x) figure%%产生一个屏幕 plot(x,y)%%打印坐标 title(ysin(x))%%标题 xlabel(…...

验证 kubelet 服务已经停止并且不再生成错误日志

要验证 kubelet 服务已经停止并且不再生成错误日志&#xff0c;可以按照以下步骤进行操作&#xff1a; 1. 检查 kubelet 服务状态 首先&#xff0c;确认 kubelet 服务已经停止。 Bash 深色版本 sudo systemctl status kubelet 你应该看到类似以下的输出&#xff0c;表示服…...

【Linux】进程控制-----进程替换

目录 一、为什么要进行进程替换&#xff1a; 二、进程替换的原理&#xff1a; 三、exec家族&#xff1a; 1、execl&#xff1a; 2、execlp&#xff1a; 3、execv&#xff1a; 4、execvp&#xff1a; 5、execle和execve ​编辑 putenv&#xff1a; 一、为什么要进行进程…...

安装SQL Server 2022提示需要Microsoft .NET Framework 4.7.2 或更高版本

安装SQL Server 2022提示需要Microsoft .NET Framework 4.7.2 或更高版本。 原因是&#xff1a;当前操作系统版本为Windows Server 2016 Standard版本&#xff0c;其自带的Microsoft .NET Framework 版本为4.6太低&#xff0c;不满足要求。 根据报错的提示&#xff0c;点击链接…...

使用ECharts创建带百分比标注的环形图

在数据可视化领域&#xff0c;环形图是一种非常有效的图表类型&#xff0c;它能够清晰地展示各部分与整体的关系。今天&#xff0c;我们将通过ECharts来创建一个带百分比标注的环形图&#xff0c;并详细解释如何实现这一效果。 1. 数据准备 首先&#xff0c;我们定义了一些基础…...

学习threejs,设置envMap环境贴图创建反光效果

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.CubeTextureLoader 立…...

go语言里的mkdir mkdirall有什么区别?

在Go语言中&#xff0c;os.Mkdir 和 os.MkdirAll 都是用来创建目录的函数&#xff0c;但它们之间存在一些关键的区别。 ### os.Mkdir - **功能**&#xff1a;os.Mkdir 用于创建一个单一的目录。如果该目录已经存在&#xff0c;则会返回一个错误。 - **参数**&#xff1a; - na…...

使用Python OpenCV实现图像形状检测

目录 一、环境准备 二、读取和预处理图像 读取图像 灰度化 滤波去噪 三、边缘检测 四、查找轮廓 五、绘制轮廓 六、形状分类 七、显示结果 八、完整代码示例 九、总结 图像形状检测是计算机视觉领域中的一项关键技术,广泛应用于工业自动化、机器人视觉、医学图像处…...

继上一篇,设置弹框次数以及自适应图片弹框,部分机型(vivo)老手机不显示的问题

上一篇写的本来测试好多型号都无事, 今天下午公司的战斗机vivo横空冒出… 晕 弹框直接显示都出不来了,现在还有用这种老的机型的,但是没办法咯~ 前端遇到这种兼容性的问题就要勇于解决 主要解决了这几点: // 添加图片加载事件 <imgv-if"imageUrl":src"image…...

基于RISC-V 的代理内核实验(使用ub虚拟机安装基本环境)

1.安装支撑软件 第一步&#xff0c;安装依赖库 RISC-V交叉编译器的执行仍然需要一些本地支撑软件包&#xff0c;可使用以下命令安装&#xff1a; $ sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bis…...

【MMKV】HarmonyOS中的优秀轻量化存储方式

MMKV 引言 在移动应用开发的世界里&#xff0c;数据存储和管理是至关重要的一环。随着技术的不断进步&#xff0c;开发者们对于高性能、轻量级、易用的数据存储解决方案的需求日益增长。MMKV&#xff08;Memory Mapped Key-Value&#xff09;正是这样一个开源的高性能key-val…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...