Java 反射总结和使用
来源:互联网 发布:mac邮件图片显示问号 编辑:程序博客网 时间:2024/06/10 19:44
什么是反射
官方有段介绍是这么说的
Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine.
什么意思呢,就是说反射通常用于需要能够检查或修改Java虚拟机中运行的应用程序的运行时行为的程序。
不是很好懂,我们说下反射能做什么吧。
- 反射可以在运行时动态生成某个类的实例。
- 反射可以在运行时获取某个类的任何的变量并修改变量的值。
- 反射可以在运行时执行某个类的任何方法。
如何使用反射
我们针对上面的情况一一说一下如何使用。
我们先定义一个 com.reflect.Demo.java 用来做我们后续的实验。
package com.reflect;public class Demo { public String pubStr = "public_string"; private String priStr = "private_string"; private String getPriStr(String testParam) { pubStr = testParam; return priStr; } private String getPriStr() { return priStr; } public Demo() { } private Demo( String priStr ) { this.priStr = priStr; } @Override public String toString() { return "Demo{" + "pubStr='" + pubStr + '\'' + ", priStr='" + priStr + '\'' + '}'; }}
在运行时动态生成某个类的实例
// 反射第一步是获取类的 class , 一般有 3 种写法Class demoClass = Class.forName("com.reflect.Demo");// demoClass = Demo.class;// demoClass = new Demo().getClass();// 获取无参构造函数Constructor constructor = demoClass.getDeclaredConstructor();// 设置可以访问constructor.setAccessible(true);// 根据构造方法创建实例Object demo = constructor.newInstance();// 获取有参构造函数Constructor constructor1 = demoClass.getDeclaredConstructor(String.class);// 设置可以访问constructor1.setAccessible(true);// 根据构造方法创建实例Object demo1 = constructor1.newInstance("I am String");
下面介绍一种通用的获取某个类的实例的方法
/** * 运用反射,通过默认的构造方法获取某个类的实例 * * @param className * @return */ public static Object getObjectInstance(String className, Object... args) { try { Class[] classes = new Class[args.length]; for (int i = 0; i < args.length; i++) { classes[i] = args[i].getClass(); } Class objClass = Class.forName(className); Constructor constructor = objClass.getDeclaredConstructor(classes); constructor.setAccessible(true); return constructor.newInstance(args); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return new Object(); }
在运行时获取某个类的任何的变量并修改变量的值
下面的代码会告诉大家如何获取 Demo.java 的一个实例的变量 (priStr) 并对其赋值。
// 无参构造方法 new 的实例,里面的 priStr 值为 private_stringDemo demo = new Demo();// 获取 demo 的 classClass demoClass = demo.getClass();// 获取 priStr 的 Field Field priStrField = demoClass.getDeclaredField("priStr");// 设置可以访问priStrField.setAccessible(true);// 取 priStr 的值// 要取的是 demo 这个实例的 priStr , 所以需要传入 demoObject priStrValue = priStrField.get(demo); // 修改 priStr 的值// 要修改的是 demo 这个实例, 所以需要传入 demopriStrField.set(demo,"I am Private String");
下面介绍一种通用的获取属性的方法
/** * 获取某个变量的值 * * @param obj 待取值的类 * @param fieldName 待取值的变量的变量名 * @return */ public static Object getFieldValue(Object obj, String fieldName) { try { Field field = obj.getClass().getDeclaredField(fieldName); field.setAccessible(true); return field.get(obj); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return new Object(); } /** * 设置某个类的某个变量的值 * * @param obj * @param fieldName * @param fieldValue * @return */ public static boolean setFieldValue(Object obj, String fieldName, Object fieldValue) { try { Field field = obj.getClass().getDeclaredField(fieldName); field.setAccessible(true); field.set(obj, fieldValue); return true; } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return false; }
在运行时执行某个类的任何方法
下面的代码会告诉大家如何获取 Demo.java 的一个方法(getPriStr) 并调用此方法。
// 无参构造方法 new 的实例,里面的 priStr 值为 private_stringDemo demo = new Demo();// 获取 demo 的 classClass demoClass = demo.getClass();// 获取无参 getPriStr 对应的 Method Method priStrMethod = demoClass.getDeclaredMethod("priStr");// 设置可以访问priStrMethod.setAccessible(true);// 调用此方法Object priStr = priStrMethod.invoke(obj);// 获取有参 getPriStr 对应的 Method Method priStrMethod1 = demoClass.getDeclaredMethod("priStr",String.class);// 设置可以访问priStrMethod1.setAccessible(true);// 调用此方法Object priStr1 = priStrMethod1.invoke(obj,"I am testParam");
下面介绍一种通用的调用对象的方法
/** * 调用某个方法 * @param obj * @param methodName * @param args * @return */ public static Object invokMethod(Object obj, String methodName, Object... args) { try { Class[] classes = new Class[args.length]; for (int i = 0; i < args.length; i++) { classes[i] = args[i].getClass(); } Method method = obj.getClass().getDeclaredMethod(methodName, classes); method.setAccessible(true); method.invoke(obj,args); return method.invoke(obj, args); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return new Object(); }
更多用法可参考 DEMO
0 0
- Java 反射总结和使用
- Java 反射 使用总结
- Java 反射 使用总结
- Java 反射 使用总结
- Java反射使用总结
- Java反射学习总结终(使用反射和注解模拟JUnit单元测试框架)
- java 反射的一些使用总结
- java 基础之反射使用总结
- Java中的反射总结和实例全
- Java反射和注解一些总结
- Java反射学习总结四(动态代理使用实例和内部原理解析)
- 【Java】Java反射总结
- java 反射和 工厂模式结合使用
- java反射机制浅析和使用
- Java和Android反射使用记录
- java 泛型使用和反射
- java 反射的理解和使用
- Java反射和注解的使用
- 尝鲜QM 4.0.0 -- 安装、注册、试用子机功能
- Volley发起网络请求及Gson
- 学习小记-ubutun下的Sublime Text 3的安装与使用
- 【备忘】JAVA SE+JSP+Servlet+Oracle+SSH+J2EE项目实战 JAVA全套视频教程 下载
- Android客户端和服务端如何使用Token和Session
- Java 反射总结和使用
- 学习Token
- 【备忘】北风网-手机进销存系统 共80课时 下载
- 坚持#第118天~按每日安排来!
- Python实战计划学习作业2-2
- centos6 python 安装 sqlite 解决 No module named ‘_sqlite3′
- 自定义ViewGroup之拖拽图片显示(不知道起什么名字..)
- 异常控制流
- PAT-basic level-1008