在《Java解惑》上面看到第八十三例--诵读困难者,要求使用非反射实现单例对象的拷贝。查阅了部分资料,先实现通过反射拷贝对象。

1. 编写需要被拷贝的对象Person

package com.scl.j2se.reflectjavabean;

public class Person
{
public String getName()
{
return name;
} public void setName(String name)
{
this.name = name;
} public String getPassword()
{
return password;
} public void setPassword(String password)
{
this.password = password;
} public String getEmail()
{
return email;
} public void setEmail(String email)
{
this.email = email;
} public String name;
public String password;
public String email; public Person()
{
} public Person(String name, String password, String email)
{
this.name = name;
this.password = password;
this.email = email;
} //拷贝的是字段,没有对对象的方法进行拷贝
public void showMyMail()
{
System.out.println("My Email address is" + this.email);
}
}

2. 使用反射对Person对象的字段进行拷贝

package com.scl.j2se.reflectjavabean;

import java.lang.reflect.Field;
import java.lang.reflect.Method; /************************************************************************
* 版 本 号 : v1.0.0.0
* 作 者 : suncl
* 创建时间 : 2015年9月3日
* 更新时间 : 2015年9月3日
* 项目名称 : ReflectPerson.java
* 说 明 : 学习内容
* 总 结 :
* 1. 获取类型对象的方法
* 1) 使用类的class属性 .class
* Class<?> classType = Person.class;
* 2) 已知类对象,使用对象的实例方法getClass(),返回运行时的对象类型
* Person p = new Person();
* p.getClass();
* 3) 使用Class类的静态方法forName()
* Class<?> classType = Class.forName("com.scl.j2se.reflectjavabean.Person");
* 2. getDeclaredFields(),getDeclaredMethods()方法返回了类所定义的所有已声明的属性对象和方法对象
* 包含"私有"的.要对私有方法及字段进行操作,需要使用setAccessible(true);
*
************************************************************************
* Copyright @ suncl 2013 . All rights reserved.
************************************************************************/ public class ReflectPerson
{
public static void main(String[] args) throws Exception
{
Person myPerson = new Person();
myPerson.setEmail("xxx@163.com");
myPerson.setName("Lee Ming");
myPerson.setPassword("214");
Person copyPerson = (Person) copyMyObject(myPerson);
System.out.println("copyPerson name:" + copyPerson.getName() + ",password:" + copyPerson.getPassword() + ",email:" + copyPerson.getEmail());
} //使用反射拷贝对象
public static Object copyMyObject(Object obj) throws Exception
{
//获取类型对象
Class<?> classType = obj.getClass();
//System.out.println(classType.getName());
//通过构造方法创建被反射的类型
Object object = classType.getConstructor().newInstance(); Field[] fields = classType.getDeclaredFields(); for (Field field : fields)
{
//获取所有属性的访问权限
field.setAccessible(true);
//获取字段名称,根据字段名称生成对应的方法名,用于反射
String fieldName = field.getName();
String methodName = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
String getStr = "get" + methodName;
String setStr = "set" + methodName; //调用原对象的get方法为拷贝对象的set方法赋值
Method getMethod = classType.getMethod(getStr);
Method setMethod = classType.getMethod(setStr, field.getType()); Object getMethodResult = getMethod.invoke(obj);
//调用set方法把原对象的值复制到拷贝对象
setMethod.invoke(object, getMethodResult); }
return object;
}
}

最后,通过本次的代码编写初步了解了反射的使用。同时在学习完以后产生了一些疑问:

1)严格意义上的对象拷贝应该包含引用对象的拷贝,以上的内容只拷贝了值类型字段
2)方法也是属于对象,但拷贝对象方法是否有用?同样地程序也没有对属性的get方法进行拷贝,只是把对象的值set到另一个对象当中

3)myEclipse里面是否能像visual studio那样查看对象地址...

Java 使用反射拷贝对象一般字段值的更多相关文章

  1. [源码]Literacy 快速反射读写对象属性,字段

    Literacy 说明 Literacy使用IL指令生成方法委托,性能方面,在调用次数达到一定量的时候比反射高很多 当然,用IL指令生成一个方法也是有时间消耗的,所以在只使用一次或少数几次的情况,不但 ...

  2. java使用反射给对象属性赋值的两种方法

    java反射无所不能,辣么,怎么通过反射设置一个属性的值呢? 主程序: /** * @author tengqingya * @create 2017-03-05 15:54 */ public cl ...

  3. java通过反射拷贝两个对象的同名同类型变量

    深拷贝和浅拷贝 首先对象的复制分为深拷贝和浅拷贝,关于这两者的区别,简单来说就是对于对象的引用,在拷贝的时候,是否会新开辟一块内存,还是直接复制引用. 两者的比较也有很多,具体可以看这篇文章: htt ...

  4. 利用反射获取对象中的值等于x的字段

    Field[] field = behavior.getClass().getDeclaredFields(); for (int i = 0; i < field.length; i++) { ...

  5. Java使用反射通过对象属性获取属性的值

    代码: // 通过属性获取传入对象的指定属性的值 public String getValueByPropName(Student student, String propName) { String ...

  6. java使用反射强制给private字段赋值

    今天项目中遇到了一个问题,要调用一个类,并获取这个类的属性进行赋值然后将这个类传递到方法中做为参数. 实际操作时才发现,这个类中的字段属性是私有的,不能进行赋值!没有提供公有的方法.而这个类又是打包成 ...

  7. java利用反射获取对象前后修改的内容(用于日志记录)

    import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...

  8. Java中List根据对象的属性值进行数据库group by功能的操作

    public class test { public static void main(String[] args) { List<Bill> list = new test().setO ...

  9. C#通过反射获得对象所有属性和值

    C#获得对象的所有属性和值 public void GetPros() { UserInfo userInfo = new UserInfo(); userInfo.ID = ; userInfo.N ...

随机推荐

  1. Css基础-派生选择器

    如果要修改li strong 里面文字的颜色可以这样写样式 派生选择器: li strong { color:red; } 效果:

  2. 【Cocos2d-X开发学习笔记】第09期:渲染框架之菜单类(CCMenu)的使用

    本系列学习教程使用的是cocos2d-x-2.1.4(最新版为3.0alpha0-pre) ,PC开发环境Windows7,C++开发环境VS2010    一.菜单项(CCMenuItem) 菜单项 ...

  3. hiberante中get和load方法的区别

    1.从返回结果上对比: load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常 get方法检索不到的话会返回null 2.从检索执行机制上对比: ...

  4. JavaScript toFixed() 方法

    定义和用法toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 语法NumberObject.toFixed(num) 参数 描述num 必需.规定小数的位数,是 0 ~ 20 ...

  5. 如何编写程序设置Android来电铃声

    我们在拿到新手机后通常会为其设置来年铃声,那么怎样通过代码来设置Android来电铃声,本文就为大家实例讲解下. 1.如果读到的是音频文件路径,需要先将音乐文件插入到多媒体库. Java代码 //设置 ...

  6. MySQL 中的两种临时表

    来源:阿里云RDS - 数据库内核组 链接:http://mysql.taobao.org/monthly/2016/06/07/ 外部临时表 通过CREATE TEMPORARY TABLE 创建的 ...

  7. mysql之sql语句细节问题汇总

    一.mysql count distinct null 使用注意事项 1  用一个例子来讲解一个问题,现在又一个库表hello,表内容如下: id     name 1      Null 2     ...

  8. 路径(keyPath)、键值编码(KVC)和键值观察(KVO)

    键路径 在一个给定的实体中,同一个属性的所有值具有相同的数据类型. 键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制. - 键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接 ...

  9. View绘制详解(四),谝一谝layout过程

    上篇博客我们介绍了View的测量过程,这只是View显示过程的第一步,第二步就是layout了,这个我们一般译作布局,其实就是在View测量完成之后根据View的大小,将其一个一个摆放在ViewGro ...

  10. aggregations 详解1(概述)

    aggregation分类 aggregations —— 聚合,提供了一种基于查询条件来对数据进行分桶.计算的方法.有点类似于 SQL 中的 group by 再加一些函数方法的操作. 聚合可以嵌套 ...