如何使用Java反射?(反射篇 二)

news/2024/11/24 10:04:37/

Java反射的核心是 java.lang.reflect 包,该包提供了一组类和接口,用于在运行时获取类的信息并操作类的成员,主要涉及的类包括 Class 、 Field 、 Method 和 Constructor 。

1. 获取字节码对象(Class)

有三种方式获取:

  • Class这个类里面的静态方法forName(“全类名”)(最常用)
  • 通过class属性获取
  • 通过对象获取字节码文件对象

示例:

	// 方式1:使用对象的 .class 属性MyClass obj1 = new MyClass();Class<?> clazz1 = obj1.getClass();// 方式2:使用类的 .class 属性Class<?> clazz2 = MyClass.class;// 方式3:使用 Class.forName() 方法//Class.forName("类的全类名"): 全类名 = 包名 + 类名Class<?> clazz3 = 	Class.forName("com.test.MyClass");

2. 获取构造方法对象(Constructor)

基本方法介绍

方法名说明
Constructor<?>[] getConstructors()获得所有的构造(只能public修饰)
Constructor<?>[] getDeclaredConstructors()获得所有的构造(包含私有方法)
Constructor getConstructor(Class<?>… parameterTypes)获取指定构造(只能public修饰)
Constructor getDeclaredConstructor(Class<?>… parameterTypes)获取指定构造(包含私有方法)

示例:

//获取类对象
Class clazz = MyClass.class;//所有构造方法
Constructor[] constructors1 = clazz.getConstructors();//获取所有构造(带私有的)
Constructor[] constructors2 = clazz.getDeclaredConstructors();//获取指定的空参构造
Constructor con1 = clazz.getConstructor();
//获取具有String和int参数的构造方法对象
Constructor con2 = clazz.getConstructor(String.class,int.class);//获取指定的构造(所有构造方法都可以获取到)
Constructor con3 = clazz.getDeclaredConstructor();
Constructor con4 = clazz.getDeclaredConstructor(String.class);

3. 根据构造方法对象来创建类实例对象

关键方法:newInstance()

//获取类对象
Class clazz = Class.forName("com.test.MyClass");
//1.获取空参的构造方法对象
Constructor con1 = clazz.getConstructor();
//创建实例对象
MyClass instance1 = (MyClass) con1.newInstance();//2.获取有参构造方法对象(所有)
Constructor con2 = clazz.getDeclaredConstructor(String.class, int.class);
//临时修改构造方法的访问权限(暴力反射)
con2.setAccessible(true);
//直接创建实例对象
MyClass instance2= (MyClass) con2.newInstance("zhangsan", 23);

4. 获取成员变量对象并操作

基本方法介绍

方法名说明
Field[] getFields()返回所有成员变量对象的数组(只能拿public的)
Field[] getDeclaredFields()返回所有成员变量对象的数组,存在就能拿到(包含私有)
Field getField(String name)返回单个成员变量对象(只能拿public的)
Field getDeclaredField(String name)返回单个成员变量对象,存在就能拿到(包含私有)
void set(Object obj, Object value)赋值
Object get(Object obj)获取值

示例:

//原对象
MyClass obj=new MyClass("张三",18);
//类对象
Class clazz = Class.forName("com.test.MyClass");
//1. 获取所有成员变量的对象(Field对象)只能获取public修饰的
Field[] fields1 = clazz.getFields();
//2. 获取所有成员变量的对象
Field[] fields2 = clazz.getDeclaredFields();
//3.获取单个(根据名字)
Field field3 = clazz.getField("name");
//4. 获取单个成员变量(包括私有)
Field field4 = clazz.getDeclaredField("age");//根据对象修改属性
field3.set(obj,"李四")
//获取新属性
String result = (String)field3.get(s);
System.out.println(result);

5. 获取成员方法对象和操作

基本方法介绍

方法名说明
Method[] getMethods()返回所有成员方法对象的数组(只能拿public的包含父类方法
Method[] getDeclaredMethods()返回所有成员方法对象的数组,存在就能拿到(包括私有,只能是本类方法)
Method getMethod(String name, Class<?>… parameterTypes)返回单个成员方法对象(只能拿public的)
Method getDeclaredMethod(String name, Class<?>… parameterTypes)返回单个成员方法对象,存在就能拿到 (包括私有)
Object invoke(Object obj, Object… args)根据对象运行方法

示例:

Class clazz = Class.forName("com.test.MyClass");
//可以获取**父类**中public修饰的方法
Method[] methods1 = clazz.getMethods();
//获取包含参数的
Method methods2 = clazz.getMethod("show",String.class);
//……其他类似//执行操作
//原对象
MyClass obj=new MyClass();
//如果方法没有返回值,则不需要接收
String result = (String) methods2.invoke(obj, "hello java");
System.out.println(result);

上一篇:了解Java反射原理


http://www.ppmy.cn/news/1145475.html

相关文章

Spring源码解析(十二):TransactionInterceptor事务拦截器

Spring源码系列文章 Spring源码解析(一)&#xff1a;环境搭建 Spring源码解析(二)&#xff1a;bean容器的创建、默认后置处理器、扫描包路径bean Spring源码解析(三)&#xff1a;bean容器的刷新 Spring源码解析(四)&#xff1a;单例bean的创建流程 Spring源码解析(五)&…

【QT开发笔记-基础篇】| 第四章 事件QEvent | 4.5 键盘事件

本章要实现的整体效果如下&#xff1a; QEvent::KeyPress ​ 键盘按下时&#xff0c;触发该事件&#xff0c;它对应的子类是 QKeyEvent QEvent::KeyRelease ​ 键盘抬起时&#xff0c;触发该事件&#xff0c;它对应的子类是 QKeyEvent 本节通过两个案例来讲解这 2 个事件&…

springboot项目中后台文件上传处理

参考地址:http://www.gxcode.top/code 文件上次核心处理代码: @Autowired private FileUpload fileUpload; //获取资源对象:file-upload-prod.properties@ApiOperation(value = "用户头像修改", notes = "用户头像修改", httpMethod =

Typescript 综合笔记:解读一个github中的React 网页

1 repository来源和效果 zhitern/ntu-scse22-0163-web (github.com) 2 核心代码异同&#xff08;相比于初始创建的代码&#xff09; 2.1 index.html 和初始创建的是一样的 2.2 App.css 和初始创建的是一样的 2.3 index.tsx 唯一”不一样“的是紫色部分,tsx文件中多了一个…

C#导出本机Win32native dll

C# 使用 "3f/DllExport" 工具导出C风格的本机函数 [文 / 张赐荣] 首先&#xff0c;让我们来了解一下什么是争渡读屏软件&#xff0c;以及什么是争渡文本预处理API。争渡读屏软件是一款屏幕朗读软件&#xff0c;用于协助视力障碍人士操作电脑。 争渡文本预处理API是一…

vue,前端打包项目、部署上线

前端项目是在本地的IDE开发的。流程是&#xff1a;开发》打包》上线到生产环境》使用。 vue脚手架只是开发过程中,协助开发的工具,当真正开发完了&#xff0c;脚手架不参与上线。 这时候要用到打包了。 打包后,可以生成,浏览器能够直接运行的网页>就是需要上线的源码! 打…

maven的pom.xml文件显示被删除

文章目录 1.问题情况2.问题分析3.问题解决 1.问题情况 2.问题分析 这些 pom.xml 文件被 maven 视为了忽略文件。 3.问题解决 路径&#xff1a;File --> Settings --> Build&#xff0c;Execution&#xff0c;Deployment --> Build Tools --> Maven --> Ignor…

对比纯软开与嵌入式硬件开发谁更好呢?

对比纯软开与嵌入式硬件开发谁更好呢&#xff1f; 你的纠结和犹豫是理解的&#xff0c;职业选择确实是一个重要的决策。我明白你在嵌入式和软件开发之间犹豫不决的原因。让我给你提供一些建议&#xff0c;帮助你做出更明智的决定。最近很多小伙伴找我&#xff0c;说想要一些嵌入…