zoukankan      html  css  js  c++  java
  • 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);
        }
    }
    View Code

    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;
        }
    }
    View Code

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

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

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

  • 相关阅读:
    Hadoop脚本:自动搜集所有节点上的异常信息
    Hadoop脚本:重新初始化所有节点
    Hadoop入门:最应该看的几篇文章
    Hadoop脚本:用Streaming方式使用Hadoop
    [SaaS研究] SaaS在中国 / 中国的Salesforce / 阿里巴巴 / 阿里软件 [ 转 ]
    Hadoop常见问题与解决方法汇总
    Hadoop:你所不知道的一些相关项目
    Hadoop MapReduce 学习
    有多少项目准备和Hadoop比拼?
    开放源码的云计算平台:触手可及的云计算 [ 原 ]
  • 原文地址:https://www.cnblogs.com/doucheyard/p/4783333.html
Copyright © 2011-2022 走看看