Java 使用反射拷贝对象一般字段值

在《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("[email protected]");
        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那样查看对象地址...

时间: 2024-10-13 14:41:13

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

使用反射设置对象的字段值

package com.sadhu; import java.util.*; import java.lang.reflect.*; /** */ public class Sample {     public static void main(String[] args)throws Exception     {         Class cl = Class.forName("com.sadhu.ReflectTest");         Object rt = cl.ne

Java利用反射访问对象的私有成员

当我们使用反射为java对象的全部字段逐一赋值的时候,私有字段是不允许直接访问的. 在java.lang.reflect当中,有几个比较实用的API可以解决: getDeclaredFields() :获得所有访问级别的字段 setAccessible(boolean flag): 修改类成员的可访问性 下面以一个JavaBean 对象 转 DBObject 对象的方法为例: public static DBObject bean2DbObject(DBObject dbObject, PicI

java 使用反射转换对象 Object to Map

Object to Map 转换的三种方法 就是把对象以及其对应的属性名 和属性值, 映射到一个Map中 import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.

泛型约束和利用反射修改对象属性的值

周日了都,昨天休息了一天,今天想想得敲敲代码练习一下,如下关于泛型约束和利用反射修改对象属性的值的, 都挺简单的,呵呵,但时间一长,不经常使用还容易忘记在此就当记录一下了, 首先泛型代码一般是如下的情形: 加了泛型约束,只允许引用类型并且是只能是无参数的构造函数的类型才能传入,也就是不允许给类构造参数传递实参,否则将报错. 错误 1 “XXXXXX.pros”必须是具有公共的无参数构造函数的非抽象类型,才能用作泛型类型或方法“ 1 public static T GetObject<T>(T

java反射获取对象的属性值和对象属性中的子属性值

近段时间在做web项目,前端使用的是jQuery EasyUI. 为方便需要,准备做一个前端通用的Datagird导出Excel功能,博主也考虑过思路和最终功能,1.前端选中行导出:2.当前页导出:3.当前过滤条件导出. 想偷懒在网上找找已有的代码改改,发现大部分只能满足个别需求,使用JS导出只能满足前端,使用代码才能实现3功能. ...... 好了,说了一堆废话,回归正题,本文是在做通用自定义字段导出时所需要,根据属性名去查找对象和子对象,找到对应属性值,抓取回来放到Excel中. 直接上代码

通过反射判断对象的属性值是否为空

问题产生场景? 在项目开发过程中我采用了表单内部嵌套列表的形式提交数据,将表单于列表数据同时提交保存.   有时候管理人的出资人结构我新增了多条  这时候并没有真正的保存到数据库,而是保存在了页面前端临时保存等待真正的提交  我操作删除 这时候删除实现的方式是 function delFundManage(obj){ $(obj).parent().parent().remove();} 移除了 但是在创建列表的时候 进行移除第一个 arr[1]  这里并没有将修改为arr[0] 这里提交到后台

java 利用反射修改对象中的list类型字段中的值。

这两天没事学习下了反射.通过反射我们可以修改对象中的字段的值. 就如下面这段代码 Grade grade=new Grade(); Field f=Grade.class.getDeclaredField("name"); f.setAccessible(true); f.set(grade, "三年级一班"); 这是so easy的,这时我想到了要是list类型的字段该怎么通过反射修改呢. 于是我就尝试了下,最终做了出来. 先准备两个类. public class

反射获取对象的属性值

1 > bean 对象 package com.whbs.bean; public class UserBean { private Integer id ; private int age ; private String name ; private String address ; public UserBean(){ System. out .println( " 实例化 " ); } public Integer getId() { return id ; } publ

反射_4.案例:使用反射替换对象所有字符串值

package com.day2; import java.lang.reflect.Field; public class T4_ReflectReplaceString { public static void main(String[] args) { Demo demo1 = new Demo(); try { //调用该方法 reflectReplaceString(demo1); System.out.println(demo1); } catch (Exception e) { e