利用反射进行对象拷贝的例子

如下例程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反射学习二的更多相关文章

  1. Java反射学习系列-绪论

    Java反射学习系列-绪论 https://blog.csdn.net/hanchao5272/article/details/79358924

  2. Java反射学习总结终(使用反射和注解模拟JUnit单元测试框架)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 本文是Java反射学习总结系列的最后一篇了,这里贴出之前文章的链接,有兴趣的可以打开看看. ...

  3. Java反射学习总结四(动态代理使用实例和内部原理解析)

    通过上一篇文章介绍的静态代理Java反射学习总结三(静态代理)中,大家可以发现在静态代理中每一个代理类只能为一个接口服务,这样一来必然会产生过多的代理,而且对于每个实例,如果需要添加不同代理就要去添加 ...

  4. Java开发学习(二十二)----Spring事务属性、事务传播行为

    一.事务配置 上面这些属性都可以在@Transactional注解的参数上进行设置. readOnly:true只读事务,false读写事务,增删改要设为false,查询设为true. timeout ...

  5. Java开发学习(二十四)----SpringMVC设置请求映射路径

    一.环境准备 创建一个Web的Maven项目 参考Java开发学习(二十三)----SpringMVC入门案例.工作流程解析及设置bean加载控制中环境准备 pom.xml添加Spring依赖 < ...

  6. Java开发学习(二十五)----使用PostMan完成不同类型参数传递

    一.请求参数 请求路径设置好后,只要确保页面发送请求地址和后台Controller类中配置的路径一致,就可以接收到前端的请求,接收到请求后,如何接收页面传递的参数? 关于请求参数的传递与接收是和请求方 ...

  7. Java开发学习(二十六)----SpringMVC返回响应结果

    SpringMVC接收到请求和数据后,进行了一些处理,当然这个处理可以是转发给Service,Service层再调用Dao层完成的,不管怎样,处理完以后,都需要将结果告知给用户. 比如:根据用户ID查 ...

  8. Java开发学习(二十七)----SpringMVC之Rest风格解析及快速开发

    一.REST简介 REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格 当我们想表示一个网络资源的时候,可以使用两种方式: 传统风格资源描 ...

  9. Java开发学习(二十八)----拦截器(Interceptor)详细解析

    一.拦截器概念 讲解拦截器的概念之前,我们先看一张图: (1)浏览器发送一个请求会先到Tomcat的web服务器 (2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源 (3)如 ...

随机推荐

  1. HDU3085(KB2-G 双向bfs)

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. 在arcgis使用python脚本进行字段计算时对中文的处理方案

    一.引言 在arcgis打开一个图层的属性表,可以对属性表的某个字段进行计算,但是在平常一般都是使用arcgis提供的字段计算器的界面进行傻瓜式的简答的赋值操作,并没有使用到脚本对字段值进行逻辑的操作 ...

  3. 177. [USACO Jan07] 有限制的素数

    177. [USACO Jan07] ★   输入文件:qprime.in   输出文件:qprime.out   简单对比 时间限制:1 s   内存限制:128 MB Farmer John 开始 ...

  4. 为样式找到应用目标-CSS选择器

    1,常用选择器:元素(标签/简单)选择器.ID选择器.类选择器.后代选择器(可以将类或者ID应用于它们的祖先,然后使用后代选择器来定位) 2,伪类:有时候,我们需要根据文档结构之外的其他条件对元素应用 ...

  5. android IO流操作文件(存储和读取)

    存储文件: public class FileOperate extends Activity { private static final String FILENAME = "mydat ...

  6. SpringBoot 之HelloController

    1.搭建环境 1.1 新建一个maven项目,一路下一步 1.2 打开pom 文件,首先增加<parent></parent>标签: <parent> <gr ...

  7. Python Socket实现简单web服务器

    #!/usr/bin/python env # coding:utf-8 import socket ip_port = ('127.0.0.1', 80) back_log = 10 buffer_ ...

  8. zTree设置异步加载后展开

    //不能直接配置展开属性 因为没有数据,需要添加回调函数,异步加载成功展开 callback: { onAsyncSuccess: zTreeOnAsyncSuccess } //异步加载成功回调函数 ...

  9. leetCode题解之根据字符出现的频率排序

    1.题目描述 Given a string, sort it in decreasing order based on the frequency of characters. Example 1: ...

  10. log4j配置详解(非常详细)

    Log4J的配置文件(Configuration File)就是用来设置记录器的级别.存放器和布局的,它可接key=value格式的设置或xml格式的设置信息.通过配置,可以创建出Log4J的运行环境 ...