Java反射总结
时间:2019-11-01
本文章向大家介绍Java反射总结,主要包括Java反射总结使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1:所写的东西都经过验证,保证正确,环境jdk8,eclipse
2:拒绝伸手党,会给出详细的推理过程
3:在例子中,尽量以生产环境中实际代码为例,那种固定值什么的没什么意义
问题: 1:想获取调用方法所需要的参数 2:参数是以json形式存储,在字符串的字段里 3: 传入的参数可以与方法的参数顺序不一致 解决方案: 1:涉及到的技术:反射,json转换 2:思路: (1):先将json转换成对应的bean (2):通过反射找到对应方法,获取对应的参数 (3):通过反射获取参数对应的bean,对应参数名称的值, (4):注入 3:可能存在的问题:参数类型未校验,考虑到时json形式,就未校验 4:上代码(注意:这里的所有参数都是动态,我这里为了测试/方便看才写的固定值) public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//json 转换 net.sf.json.JSONObject; String str = "{\r\n" + " \"aa\": \"zhangsan\",\r\n" + " \"bb\": 1\r\n" + "}";
//注意实例化 Test test = new Test(); test = (Test) JSONObject.toBean(JSONObject.fromObject(str), Test.class); Class<?> clazz = HelloService.class;
//获取类中的方法 Method[] methods = clazz.getMethods(); Class<?>[] parameterTypes = null; Parameter[] parameters; Object[] obj; for (Method n : methods) { if ("sayHello".equals(n.getName())) { parameterTypes = n.getParameterTypes(); parameters = n.getParameters(); // Class clazzTest = test.getClass(); // Object o1 = clazzTest.newInstance(); for (int i = 0; i < parameters.length; i++) {
//获取方法参数对应的方法名,这里只有jdk1.8及以上支持 String parameterName = parameters[i].getName(); //获取类中的属性 Field field = test.getClass().getDeclaredField(parameterName);
//设置类中私有属性可见 field.setAccessible(true);
//获取属性值 Object obj1 = field.get(test); } } } //获取目标方法 Method method = clazz.getMethod("sayHello", parameterTypes);
//为目标方法注值,第二个参数是值 method.invoke(clazz.newInstance(), test); }
5:拓展
(1):这张图片是常用的反射方法
(2)这是一个别人写的例子,还不错 import java.lang.reflect.Constructor; import java.lang.reflect.*; /*Class:代表一个字节码文件的对象,每当有类被加载进内存,JVM就会在堆上给 * 该类创建一个代表该类的对象。每个类的Class对象是的。 *Class类没有构造方法,获得类对应的Class方法有3种 *1.:getClass()、2.类、接口.class 、3.Class.forName("类全名"); *比较推荐使用第3种方式,使用前两种方式程序扩展性不好。 * *Class类中定义了许多关于获取类中信息的方法: *1.获得该类的构造方法,属性,方法、实例的方法。包含特定情况的获得 *2.获得该类的父类,实现的接口,该类的类加载器,类名、包名等。 *3.判断该类的具体是接口、类、内部类等 *4.方法中加Declared表示可以获得本类定义的任何方法和属性 * *注意:关于获得到的方法、属性、构造器的具体操作被封装在import java.lang.reflect包里面 *Method:里面最常用的方法invoke(对象,可变参数列表)--调用指定的方法 *Field:get/set;获取和修改属性值 *Constrcutor:使用newInstance(可变参数列表)--调用指定构造方法创建类的实例 *注意:私有的要调用前先去掉访问权限限制setAccssible() * */ public class ReflectionWithClass { public static void main(String[] args) throws Exception { //第一种方式获得Class对象,比较麻烦,要先创建对象,再使用对象调用方法 HelloKitty ht = new HelloKitty(); Class clazz = ht.getClass(); //第二种方式获得Class对象。使用静态的属性创建 Class clazz1 = HelloKitty.class; //使用Class对象的静态方法获得Class对象 Class clazz2 = Class.forName("HelloKitty"); //获得该类的类加载器 ClassLoader c = clazz2.getClassLoader(); System.out.println(c.toString()); Class clazz3 = String.class; System.out.println(clazz3.getClassLoader()); //获得该类的实例 Object obj = clazz2.newInstance(); //获得该类的构造器---公开的,getDeclaredConstructors()--可以获得私有的 Constructor[] con = clazz2.getDeclaredConstructors(); for(Constructor cc:con){ System.out.print(cc + " "); } //获得类的方法 Method[] mm = clazz2.getDeclaredMethods(); for(Method mmm:mm){ System.out.print(mmm + " "); } System.out.println(); //获取特定的方法 Method m = clazz2.getMethod("walk",null); System.out.println(m.toString()); Field[] f = clazz2.getDeclaredFields(); for(Field ff:f){ System.out.print(ff+ " "); } //调用指定的方法---先获取,在调用;注意私有方法先设置访问权限 Method m1 = clazz2.getMethod("walk", null); System.out.println("hahahhha"); m1.invoke(obj,null); //调用指定的构造方法创建类实例;先获取在调用 Constructor cc = clazz2.getConstructor(int.class,String.class); Object o1 = cc.newInstance(12,"blue"); //获取和修改对象的属性值 Field ffs = clazz2.getDeclaredField("age"); ffs.setAccessible(true); ffs.set(obj, 29); Object oo = ffs.get(obj); System.out.println(oo); } } class HelloKitty { private int age; public String color = "pink"; public HelloKitty() {} public HelloKitty(int age) { this.age = age; } public HelloKitty(int age,String color) { this.age = age; this.color = color; System.out.println("okokok"); } public void walk(){ System.out.println("hhhhhhhhhhhhh"); } public void talk(int i){ System.out.println(i + "----------" + age); } }
6:总结一下我理解的反射和应用场景
(1)反射的概念:可以理解成你去了一个小黑屋,里面可能有各种东西,都上了锁,你通过反射就能获取里面的东西,并且去除锁,知道东西的真正面目
(2)反射应用场景:简单来说就是“动态带有固定”,举个例子,比如我上面的例子,方法是动态的,但是方法的参数是固定的;传入的参数固定的,但是顺序未必和方法一致的;
7:最后有什么反射的问题可以随时给我留言
上面5.2是参考这篇文章:https://www.cnblogs.com/sun1993/p/7828535.html
原文地址:https://www.cnblogs.com/xiaoshahai/p/11776462.html
- silverlight 相册雏型
- Mysql优化系列(1)--Innodb引擎下mysql自身配置优化
- 一台服务器多实例mysql做主从复制
- spring AOP日志管理
- vue-route+webpack部署单页路由项目,访问刷新出现404问题
- UNIX 高手的 10 个习惯
- linux下截取给定路径中的目录部分
- 一年坎坷也曾怀疑自己,如今五冠在手的柯洁将再战AI
- 从MapX到MapXtreme2004[3]-搜索图元Feature
- git push上传代码到gitlab上,报错401/403(或需要输入用户名和密码)
- mysql下mysqladmin日常管理命令总结
- Ubuntu下SVN安装和配置
- mysql表名忽略大小写问题记录
- 当wcf遇到JSON ?
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 树状数组 _ 求逆序数
- PAT (Basic Level) Practice (中文)1012 数字分类 (20 分)
- PAT (Basic Level) Practice (中文)1018 锤子剪刀布 (20 分)
- 还在用传统的方式驱动一个通信模组?不如一起来学习下TOS的AT模组框架吧!
- 编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(一)词法分析
- Codeforces Round #199 (Div. 2)C. Cupboard and Balloons
- PAT (Basic Level) Practice (中文)1004 成绩排名 (20 分)
- PAT (Basic Level) Practice (中文)1020 月饼 (25 分)
- 201709-2ccf计算机职业资格认证考试第二题公共钥匙盒
- SAP Spartacus里cx-carousel的实现
- 技术分享 | 改写 mysqldump 解决 DEFINER 问题
- CNS图表复现04—单细胞聚类分群的resolution参数问题
- 学习Vue3.0,先从搭建环境开始
- AIM Tech Round 5 (rated, Div. 1 + Div. 2)C. Rectangles
- PAT (Basic Level) Practice (中文)1006 换个格式输出整数 (15 分)