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

如下例程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. FineReport中如何自定义登录界面

    在登录平台时,不希望使用FR默认的内置登录界面,想通过自定义登录界面实现登录操作,内置登录界面如下图: 登录界面,获取到用户名和密码的值,发送到报表系统,报表服务带着这两个参数访问认证地址进行认证. ...

  2. Angularjs 表格插件的使用

    对于相关的table组件可以使用:UI Grid (ng-grid),ng-table,smart table,Angular-Datatables,tablelite,kendo-ui中的grid. ...

  3. CSS 小结笔记之清除浮动

    浮动是一个非常好用的属性,但是有时会出现一些问题,需要进行清除浮动.例如 <!DOCTYPE html> <html lang="en"> <head ...

  4. MYSQL 的rownum

    mysql> SELECT @rownum:=@rownum+1 AS rownum, FLIGHTS.FLTID FROM (SELECT @rownum:=0) r, FLIGHTS lim ...

  5. Python爬虫实战---抓取图书馆借阅信息

    Python爬虫实战---抓取图书馆借阅信息 原创作品,引用请表明出处:Python爬虫实战---抓取图书馆借阅信息 前段时间在图书馆借了很多书,借得多了就容易忘记每本书的应还日期,老是担心自己会违约 ...

  6. 【Kettle】3、数据源连接配置

    1.各系统版本信息 System:Windows旗舰版 Service Pack1 Kettle版本:6.1.0.1-196 JDK版本:1.8.0_72 2.连接介绍 关于Kettle数据源连接方式 ...

  7. 使用Membership,您的登录尝试不成功。请重试"的解决方法

    提示信息是标准Login控件产生的,打开数据库,检查aspnet_Membership表,检查IsLockedOut字段的值是否为False, 如果为True,表示这个用户锁定了,把它改成False即 ...

  8. Python项目生成requirements.txt的多种方式

    我相信任何软件程序都会有依赖的类库,尤其现在开源如此的火爆,因为一个项目可能会有无很多的依赖的包 这个时候难道我们都要一个一个的去找到安装吗?即使你找到了依赖的包 但是呢模块的版本又有很多难道你都要装 ...

  9. 在 Windows Server Container 中运行 Azure Storage Emulator(三):运行在容器中

    上一节中,我们已经准备好了 SQL Server,那么接下来,我们要把 ASE 放到容器里了. 首先,新建 Start.ps1,内容如下: param( [Parameter(Mandatory=$t ...

  10. 铁乐学Python_day08_文件操作

    一.[基本的文件操作] 参数: 1.文件路径: 2.编码方式: 3.执行动作:(打开方式)只读,只写,追加,读写,写读! #1. 打开文件,得到文件句柄并赋值给一个变量 f = open('E:/Py ...