反射机制入门
一、什么是反射机制?
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,
可以了解任意一个对象所属的类,
可以了解任意一个类的成员变量和方法,
可以调用任意一个对象的属性和方法。
这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
二、获取Class类型对象的三种方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public static void main(String[] args) { Class c1 = null ; try { //第一种方式:Class.forName("完整类名"); c1 = Class.forName( "java.lang.String" ); Class c2 = Class.forName( "java.util.Date" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } //第二种方式:类名.class Class c3 = java.lang.String. class ; /** * 第三种方式: * 先创建对象,拿到对象的引用 * 调用对象的getClass方法拿到Class对象 */ String s = new String(); Class c4 = s.getClass(); System. out .println(c1 == c3); //true System. out .println(c3 == c4); //true,说明两个对象的内存地址是一样的 } |
三、反射获取属性Filed
User类:
1 2 3 4 5 | class User { private String name; private Integer age; private String sex; } |
反射获取User对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public static void main(String[] args) throws Exception { Class<?> demo = Class.forName( "User" ); Object obj = demo.newInstance(); // 获取这个对象 Class<?> objClass = obj.getClass(); // 获取到所有的属性 Field[] fields = objClass.getDeclaredFields(); for (Field field : fields) { // 获取修饰符 int i = field.getModifiers(); String modifier = Modifier.toString(i); // 获取属性类型 Class<?> type = field.getType(); String simpleName = type.getSimpleName(); // 获取属性名 String fieldName = field.getName(); System. out .println(modifier + " " + simpleName + " " + fieldName); } } |
输出结果:
1 2 3 | private String name private Integer age private String sex |
设置类中某个具体属性的属性值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public static void main(String[] args) throws Exception { Class user = Class.forName( "User" ); // 获取这个属性 Field name = user.getDeclaredField( "name" ); Field age = user.getDeclaredField( "age" ); // 获取要修改的对象 Object obj = user.newInstance(); // 开启属性的私有访问权限 name.setAccessible( true ); age.setAccessible( true ); // 设置值 name. set (obj, "lisi" ); age. set (obj, 24); // 打印 System. out .println(name. get (obj)); System. out .println(age. get (obj)); } |
输出结果:
1 2 | lisi 24 |
四、反射获取方法
测试类:
1 2 3 4 5 6 7 8 9 | class MethodDemo { public void m1() { } public static int m2( int i) { return i; } } |
反射获取类中的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public static void main(String[] args) throws Exception { // 获取类 Class<?> methodDemo = Class.forName( "MethodDemo" ); // 获取到所有的方法 Method[] methods = methodDemo.getDeclaredMethods(); for (Method method : methods) { // 获取方法修饰符 String modifier = Modifier.toString(method.getModifiers()); System. out .print(modifier + " " ); Class<?> returnType = method.getReturnType(); // 获取方法返回值类型 String returnTypeSimpleName = returnType.getSimpleName(); System. out .print(returnTypeSimpleName + " " ); // 获取方法的方法名 String methodName = method.getName(); System. out .print(methodName + " ( ) {\n}\n" ); // 获取方法的形参参数列表 Class<?>[] parameterTypes = method.getParameterTypes(); for (Class<?> parameterType : parameterTypes) { // 获取到的是每一个形参的类型 String simpleName = parameterType.getSimpleName(); System. out .println(simpleName); } } } |
结果:
反射获取某个类的某个特定方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import java.lang.reflect.Method; /** * @author zhangzhixi * @date 2021-5-5 9:35 */ public class Test04_获取类的某个方法 { public static void main(String[] args) throws Exception { // 1.获取这个类 Class<?> methodDemo = Class.forName( "ObtainMethodDemo" ); // 2.要想通过反射执行方法,得先创建这个对象 Object obj = methodDemo.newInstance(); // 3.获取某个类的某个特定方法 Method m2 = methodDemo.getMethod( "m2" , int . class ); Method m1 = methodDemo.getMethod( "m1" , null ); // 4.执行方法,传入参数 m1.invoke(obj, null ); Object invoke = m2.invoke(obj, 666); System. out .println( "返回值是:" + invoke); } } class ObtainMethodDemo { public void m1() { System. out .println( "m1方法执行==>hello" ); } public static int m2( int i) { return i; } } |
测试结果:
1 2 | m1方法执行==>hello 返回值是:666 |
反射获取类的构造方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import java.lang.reflect.Constructor; /** * @author zhangzhixi * @date 2021-5-5 9:49 */ public class Test05_获取某个类的某个构造方法 { public static void main(String[] args) throws Exception { // 1.获取class对象 Class<?> student = Class.forName( "Student" ); // 2.获取特定的构造方法 Constructor<?> constructor = student.getDeclaredConstructor(String. class , Integer. class ); Constructor<?> studentConstructor = student.getConstructor(); // 3.执行构造 studentConstructor.newInstance(); Object newInstance = constructor.newInstance( "张三" , 23); System. out .println(newInstance); } } class Student { private String name; private Integer age; public Student() { System. out .println( "student的无参构造方法执行!" ); } public Student(String name, Integer age) { this .name = name; this .age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\ '' + ", age=" + age + '}' ; } } |
测试结果:
1 2 | student的无参构造方法执行! Student{name= '张三' , age=23} |
反射获取父类/父接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import java.lang.reflect.AnnotatedType; /** * @author zhangzhixi * @date 2021-5-5 10:03 */ public class Test06_获取类的父类_父接口 { public static void main(String[] args) throws Exception { Class<?> aClass = Class.forName( "java.lang.String" ); // 获取父类 Class<?> superclass = aClass.getSuperclass(); System. out .println(superclass); System. out .println( "===============" ); // 获取父接口 Class<?>[] interfaces = aClass.getInterfaces(); for (Class<?> anInterface : interfaces) { System. out .println(anInterface); } } } |
测试结果:
1 2 3 4 5 | class java.lang.Object =============== interface java.io.Serializable interface java.lang.Comparable interface java.lang.CharSequence |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话