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

JAVA——反射

一、什么是反射

概述:Java反射是Java语言的一种特性,它允许程序在运行时自我检查并对内部成员进行操作。这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。具体来说,反射机制允许在运行状态中:对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,并且能改变它的属性

Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。其本质是JVM得到Class对象之后,再通过Class对象进行反编译,从而获取对象的各种信息。

应用场景:

a.解剖成员方法:赋值

b.解剖成员方法:调用

c.解剖构造方法:new对象

 Class类

在Java编程语言中,Class类是一个特殊的类,它用于表示JVM运行时的类或接口的信息。你可以把它看作是一个普通的类,但它描述的是所有的类的公共特性。

每个类在Java中都对应着一个Class对象,这个对象保存了该类的结构信息,如类名、字段、方法等。换句话说,Class类是一个反射工具,能提供很多方法用于获取类的各种信息,比如获取类名、判断该类是否是一个接口还是普通类等等。

二、反射的应用

1.获取class对象

1.Object中的getClass方法

class<?> getClass()

2.不管是基本类型还是引用类型,jvm都提供了静态成员:class

类名.class

3.Class类中的静态方法 

static Class<?> forName(String className)className:传递的是类的全限定名(包名.类名)

写类的全限定名技巧:

a.复制粘贴

b.类名回车

public class Demon01 {@Testpublic void get1() throws ClassNotFoundException {Student student = new Student();Class<? extends Student> class1=student.getClass();System.out.println(class1);Class<Student> class2=Student.class;System.out.println(class2);Class<?> class3=Class.forName("Student");System.out.println(class3);}
}

3为最通用方法,可以和properties文件结合使用

2为最常用方法

2.反射构造方法

1.获取所有public构造方法

Class中的方法:Constructor<?>[] getConstructors()->获取所有public的构造public class Demon01 {@Testpublic void get1() throws ClassNotFoundException {Class<Student> class1=Student.class;Constructor<?>[] constructors= class1.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println(constructor);}}
}

2.获取空参构造

Class中的方法:Constructor<T> getConstructors(Class<?>...parameterTypes)->获取指定public的构造parameterTypes:可变参数,传递0个或多个参数a.如果获取的是空参构造:参数不用写b.如果获取的是有参构造:参数写参数类型的class对象Constructor类中的方法:T newInstance(Object...initargs)->创建对象initargs:传递构造方法的实参public class Demon01 {@Testpublic void get1() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class<Student> class1=Student.class;Constructor<Student> constructor= class1.getConstructor();System.out.println(constructor);Student student=constructor.newInstance();System.out.println(student);}
}

利用空参构造创建对象的快捷方法

Class中的方法:
T newInstance()->根据空参对象创建对象前提:被反射的类中必须有public的空参构造

 3.获取有参构造

Class中的方法:Constructor<T> getConstructors(Class<?>...parameterTypes)->获取指定public的构造parameterTypes:可变参数,传递0个或多个参数a.如果获取的是空参构造:参数不用写b.如果获取的是有参构造:参数写参数类型的class对象Constructor类中的方法:T newInstance(Object...initargs)->创建对象initargs:传递构造方法的实参public class Demon01 {@Testpublic void get1() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class<Student> class1=Student.class;Constructor<Student> constructor= class1.getConstructor(int.class,int.class,int.class);System.out.println(constructor);Student student=constructor.newInstance(1,2,3);System.out.println(student);}
}

 4.获取私有构造

1.Constructor<?>[] getDeclaredConstructors()获取所有构造方法
2.Constructor<T> getDeclaredConstructor(类<?>...parameterTypes)->获取指定构造包括privateparameterTypes:参数类型的class对象
3.Constructor有一个父类AccessibleObject,里面有一个方法void setAccessible(boolean flag)->修改访问权限flag为true:解除私有权限(暴力反射)public class Demon01 {@Testpublic void get1() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class<Student> class1=Student.class;Constructor<Student> constructor= class1.getDeclaredConstructor(int.class);System.out.println(constructor);constructor.setAccessible(true);Student student=constructor.newInstance(1);System.out.println(student);}
}

3.反射成员方法  

 1.获取所有public成员方法

1.Class类中的方法:
Method[] getMethods()->获取所有public方法,包括父类中的public方法public static void main(String[] args) {Class<Student> clazz = Student.class;Method[] methods = clazz.getMethods();for (Method method : methods) {System.out.println(method.getName());}
}

2.获取(有参,无参)public方法

1.Class类中的方法:
Method getMethod(String name,Class<?>...parameterTypes)->获取指定的public成员方法name:方法名parameterTypes:方法参数类型的class对象
2.调用方法:Method对象中的方法Object invoke(Object obj,Object...args)->执行方法obj->根据构造new出来的对象args:方法实参->如果有参数,直接传递实参;否则不用传返回值:Object->接收被执行方法的返回值,如果方法没有返回值,不用接收

 3.操作私有方法

1.Metod[] getDeclaredMethods()->获取所有的成员方法
2.Method getDeclearedMethod(String name,类<?>...parameterTypes)->获取指定成员方法
3.解除 私有权限void setAccessible(boolean flag)->修改访问权限flag为true:解除私有权限(暴力反射)

4.反射成员变量

1.获取所有属性

Class类中的方法:
1.Filed[] getFileds()->获取所有public属性
2.Filed[] getDeclaredFileds()->获取所有属性    public static void main(String[] args) throws Exception {Class<Student> clazz = Student.class;Field[] field = clazz.getFields();for (Field field1 : field) {System.out.println(field1);}Field[] fieldds=clazz.getDeclaredFields();for (Field field2 : fieldds) {System.out.println(field2);}
}

 2.获取指定属性

1.Filed getFiled(String name)->获取指定public属性
2.Filed getDeclaredFiled(String name)->获取指定属性
3.Filed类中的方法:void set(Object obj,Object val)->为属性赋值obj:对象val:赋予的值Object get(Object obj)->获取属性值obj:对象public static void main(String[] args) throws Exception {Class<Student> clazz = Student.class;Student student = new Student();Field fields = clazz.getField("age");fields.set(student, 1);System.out.println(fields.get(student));
}  
public class Test {
public static void main(String[] args) throws Exception {Class<Student> clazz = Student.class;Student student = new Student();Field fields = clazz.getDeclaredField("id");fields.setAccessible(true);fields.set(student, 1);System.out.println(fields.get(student));}
}

 5.结合配置文件使用

步骤:
1.创建properties配置文件,配置信息

2.读取配置文件,解析配置文件
用类加载器读取配置文件

classLoader classLoader = 当前类.class.getClassLoaderO
InputStream in= classLoader.getResourceAsStream("文件名")//自动扫描resources下的文件->
可以简单理解为扫描out路径下的配置文件

3.根据解析出来的className,创建class对象
4.根据解析出来的methodName,获取对应的方法
5.执行方法

例子:

public class Demon01 {public static void main(String[] args) throws Exception {Properties properties=new Properties();InputStream in =Demon01.class.getClassLoader().getResourceAsStream("pro.properties");properties.load(in);String name = properties.getProperty("className");String methodName = properties.getProperty("methodName");Class<?> aClass=Class.forName(name);Object object=aClass.newInstance();aClass.getMethod(methodName).invoke(object);}
}
http://www.lqws.cn/news/213643.html

相关文章:

  • Windows 系统安装 Redis 详细教程
  • nginx日志的一点理解
  • Xxl-job——源码设计思考
  • Kerberos面试内容整理-未来发展趋势
  • 【大模型】大模型RAG(Retrieval-Augmented Generation)面试题合集
  • 解密LSTM(长短期记忆网络):让机器拥有记忆力的魔法网络
  • 【PhysUnits】15.17 比例因子模块 (ratio.rs)
  • 第二部分 方法,还是方法——“信管法则”的四大要点
  • 号外!PLC和安川伺服,通过Profinet转EtherCAT网关同步多个工作站的运动
  • SpiritTools:一款小而精的实用工具箱
  • 20250607在荣品的PRO-RK3566开发板的Android13系统下实现长按开机之后出现插入适配器不会自动启动的问题的解决
  • 20250607在荣品的PRO-RK3566开发板的Android13的uboot中使用gpio命令来配置GPIO的状态
  • 【Hugging Face】实践笔记:Pipeline任务、BERT嵌入层、Train任务、WandB解析
  • Python 训练营打卡 Day 38-Dataset和Dataloader类
  • Pytorch学习——自动求导与计算图
  • Spring AI与Spring Modulith核心技术解析
  • 如何判断指针是否需要释放?
  • [面试精选] 0104. 二叉树的最大深度
  • 初识redis
  • Kafka 消息模式实战:从简单队列到流处理(一)
  • c++ 静态成员变量
  • 《高精度》题集
  • 【题解-洛谷】B3622 枚举子集(递归实现指数型枚举)
  • 【Latex】Windows/Ubuntu 绘制 eps 矢量图通用方法(drawio),支持插入 Latex 数学公式
  • 一款“短小精悍的”手机录屏软件
  • 安达发|装饰材料行业APS生产排程软件:破解生产困局,智造升级新引擎
  • Java高级 |【实验八】springboot 使用Websocket
  • Spring中循环依赖问题的解决机制总结
  • day 27 装饰器函数
  • [GitHub] 优秀开源项目