Java反射学习二
利用反射进行对象拷贝的例子
如下例程ReflectTester类进一步演示了Reflection API的基本使用方法。
ReflectTester类有一个copy(Object object)方法,这个方法能够创建一个和参数object同样类型的对象,然后把object对象中的所有属性拷贝到新建的对象中,并将它返回。
这个例子只能复制简单的类,假定类的每个属性都有public类型的getXXX()和setXXX()方法。

- import java.lang.reflect.Constructor;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- public class ReflectTester
- {
- // 该方法实现对Customer对象的拷贝操作
- public Object copy(Object object) throws Exception
- {
- Class<?> classType = object.getClass();
- /* 生成新的对象的讨论
- // 获得Constructor对象,此处获取第一个无参数的构造方法的
- Constructor cons = classType.getConstructor(new Class[] {});//不带参数,所以传入一个为空的数组
- // 通过构造方法来生成一个对象
- Object obj = cons.newInstance(new Object[] {});
- // 以上两行代码等价于:
- Object obj11 = classType.newInstance(); // 这行代码无法处理构造函数有参数的情况
- //用第二个带参数的构造方法生成对象
- Constructor cons2 = classType.getConstructor(new Class[] {String.class, int.class});
- Object obj2 = cons2.newInstance(new Object[] {"ZhangSan",20});
- */
- Object objectCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
- //获得对象的所有成员变量
- Field[] fields = classType.getDeclaredFields();
- for(Field field : fields)
- {
- //获取成员变量的名字
- String name = field.getName(); //获取成员变量的名字,此处为id,name,age
- //System.out.println(name);
- //获取get和set方法的名字
- String firstLetter = name.substring(0,1).toUpperCase(); //将属性的首字母转换为大写
- String getMethodName = "get" + firstLetter + name.substring(1);
- String setMethodName = "set" + firstLetter + name.substring(1);
- //System.out.println(getMethodName + "," + setMethodName);
- //获取方法对象
- Method getMethod = classType.getMethod(getMethodName, new Class[]{});
- Method setMethod = classType.getMethod(setMethodName, new Class[]{field.getType()});//注意set方法需要传入参数类型
- //调用get方法获取旧的对象的值
- Object value = getMethod.invoke(object, new Object[]{});
- //调用set方法将这个值复制到新的对象中去
- setMethod.invoke(objectCopy, new Object[]{value});
- }
- return objectCopy;
- }
- public static void main(String[] args) throws Exception
- {
- Customer customer = new Customer("Tom",20);
- customer.setId(1L);
- ReflectTester tester = new ReflectTester();
- Customer customer2 = (Customer)tester.copy(customer);
- System.out.println(customer2.getId() + "," + customer2.getName() + "," + customer2.getAge());
- }
- }
- class Customer
- {
- private long id;
- private String name;
- private int age;
- public Customer()
- {
- }
- public Customer(String name, int age)
- {
- this.name = name;
- this.age = age;
- }
- public long getId()
- {
- return id;
- }
- public void setId(long id)
- {
- this.id = id;
- }
- public String getName()
- {
- return name;
- }
- public void setName(String name)
- {
- this.name = name;
- }
- public int getAge()
- {
- return age;
- }
- public void setAge(int age)
- {
- this.age = age;
- }
- }
参考资料:
http://www.cnblogs.com/mengdd/archive/2013/01/26/2878136.html
http://www.cnblogs.com/gulvzhe/archive/2012/01/27/2330001.html
http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
http://www.cnblogs.com/octobershiner/archive/2012/03/18/2404751.html
Java反射学习二的更多相关文章
- Java反射学习系列-绪论
Java反射学习系列-绪论 https://blog.csdn.net/hanchao5272/article/details/79358924
- Java反射学习总结终(使用反射和注解模拟JUnit单元测试框架)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 本文是Java反射学习总结系列的最后一篇了,这里贴出之前文章的链接,有兴趣的可以打开看看. ...
- Java反射学习总结四(动态代理使用实例和内部原理解析)
通过上一篇文章介绍的静态代理Java反射学习总结三(静态代理)中,大家可以发现在静态代理中每一个代理类只能为一个接口服务,这样一来必然会产生过多的代理,而且对于每个实例,如果需要添加不同代理就要去添加 ...
- Java开发学习(二十二)----Spring事务属性、事务传播行为
一.事务配置 上面这些属性都可以在@Transactional注解的参数上进行设置. readOnly:true只读事务,false读写事务,增删改要设为false,查询设为true. timeout ...
- Java开发学习(二十四)----SpringMVC设置请求映射路径
一.环境准备 创建一个Web的Maven项目 参考Java开发学习(二十三)----SpringMVC入门案例.工作流程解析及设置bean加载控制中环境准备 pom.xml添加Spring依赖 < ...
- Java开发学习(二十五)----使用PostMan完成不同类型参数传递
一.请求参数 请求路径设置好后,只要确保页面发送请求地址和后台Controller类中配置的路径一致,就可以接收到前端的请求,接收到请求后,如何接收页面传递的参数? 关于请求参数的传递与接收是和请求方 ...
- Java开发学习(二十六)----SpringMVC返回响应结果
SpringMVC接收到请求和数据后,进行了一些处理,当然这个处理可以是转发给Service,Service层再调用Dao层完成的,不管怎样,处理完以后,都需要将结果告知给用户. 比如:根据用户ID查 ...
- Java开发学习(二十七)----SpringMVC之Rest风格解析及快速开发
一.REST简介 REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格 当我们想表示一个网络资源的时候,可以使用两种方式: 传统风格资源描 ...
- Java开发学习(二十八)----拦截器(Interceptor)详细解析
一.拦截器概念 讲解拦截器的概念之前,我们先看一张图: (1)浏览器发送一个请求会先到Tomcat的web服务器 (2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源 (3)如 ...
随机推荐
- Form表单中Post与Get方法的区别
Form提供了两种数据传输的方式:get和post.虽然它们都是数据的提交方式,但是在实际传输时确有很大的不同,并且可能会对数据产生严重的影响. Form中的get和post方法,在数据传输过程中分别 ...
- 序列化模块1 json
......得到一个 字符串 的结果 过程就叫序列化 字典 / 列表 / 数字 /对象 -序列化->字符串 为什么要序列化 # 1.要把内容写入文件 序列化 # 2.网络传输数据 序列化 字符串 ...
- css points
<style type="text/css" rel="stylesheet">.a{ width:500px; height:400px;对放置图 ...
- svn 同步资源库时忽略某些文件类型和文件夹
项目开发中,开发人员经常用SVN来管理代码,在和服务器同步时,每次都看到一堆.class,.log,target等文件,这样很不舒服. 解决方法: 打开:window-->preferences ...
- Oracle EBS PO退货失败
无法读取例程 &ROUTINE 中配置文件选项 INV_DEBUG_TRACE 的值. 系统-配置文件-地点层 INC%调试%踪 是 select * from po_interface_e ...
- Oracle EBS PO 接受入库
- CentOS随笔 - 5.CentOS7安装Sql Server 2017
前言 转帖请注明出处: http://www.cnblogs.com/Troy-Lv5/ 开发环境嘛, 作为.Net系Sql Server那是必备的. 听过Sql server可以安装在Linux上了 ...
- [微信] 客服接口调用的时候返回 40003 Invalid OpenID
首先确认收件人在24小时内主动向公众号发过消息.该消息的 FromUserId 即是客服消息的 touser 参数的 OpenId 2017-05-19 更新:可以使用UTF-8了 string ur ...
- 设计标签选择器TitleSwitch
设计标签选择器TitleSwitch 效果如下: 源码如下: TitleSwitch.h 与 TitleSwitch.m // // TitleSwitch.h // TitleSwitch // / ...
- [翻译] NMBottomTabBarController
NMBottomTabBarController A customisable tab bar controller for iOS written in Objective C. It uses a ...