`
买萌大叔
  • 浏览: 7297 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用反射将一个对象的值复制给另一个对象(同一个对象或者基于同一个基类)

    博客分类:
  • java
 
阅读更多

我写了两个方法:

第一个方法是一个类的不同实例化对象,比如类A,实例化对象a1,a2,:(使用的方法是得到类的属性名)

 

[html] view plain copy
 
  1. /**  
  2.  *   
  3.  *<p>  
  4.  *@description 转换javabean ,将class2中的属性值赋值给class1,如果class1属性有值,则不覆盖  
  5.  *</p>  
  6.  *@param class1 基准类,被赋值对象  
  7.  *@param class2 提供数据的对象  
  8.  *@throws Exception  
  9.  * @see  
  10.  */  
  11. private void converJavaBean(Object class1, Object class2) {  
  12.     Class<?> clazz1 = class1.getClass();  
  13.     Class<?> clazz2 = class2.getClass();  
  14.     Field[] fields1 = clazz1.getDeclaredFields();  
  15.     Field[] fields2 = clazz2.getDeclaredFields();  
  16.     for (int i = 0; i < fields1.length; i++) {  
  17.         try {  
  18.             fields1[i].setAccessible(true);  
  19.             fields2[i].setAccessible(true);  
  20.             Object obg1 = fields1[i].get(class1);  
  21.             Object obg2 = fields2[i].get(class2);  
  22.   
  23.             if (null == fields1[i].get(class1) && null != fields2[i].get(class2)) {  
  24.                 fields1[i].set(class1, fields2[i].get(class2));  
  25.             }  
  26.         } catch (Exception e) {  
  27.             e.printStackTrace();  
  28.         }  
  29.     }  
  30. }  

第二个方法得到get和set方法进行赋值,比第一个功能强大,只要有相同的属性名都可以

 

 

[java] view plain copy
 
  1. /** 
  2.     *  
  3.     * <p> 
  4.     *  
  5.     * @description 转换javabean ,将class2中的属性值赋值给class1,如果class1属性有值,则不覆盖 
  6.     *              ,前提条件是有相同的属性名 
  7.     *              </p> 
  8.     * @param class1 
  9.     *            基准类,被赋值对象 
  10.     * @param class2 
  11.     *            提供数据的对象 
  12.     * @throws Exception 
  13.     * @author ex_dingyongbiao 
  14.     * @see 
  15.     */  
  16.    public static void converJavaBean(Object class1, Object class2) {  
  17.        try {  
  18.            Class<?> clazz1 = class1.getClass();  
  19.            Class<?> clazz2 = class2.getClass();  
  20.            // 得到method方法  
  21.            Method[] method1 = clazz1.getMethods();  
  22.            Method[] method2 = clazz2.getMethods();  
  23.   
  24.            int length1 = method1.length;  
  25.            int length2 = method2.length;  
  26.            if (length1 != 0 && length2 != 0) {  
  27.                // 创建一个get方法数组,专门存放class2的get方法。  
  28.                Method[] get = new Method[length2];  
  29.                for (int i = 0, j = 0; i < length2; i++) {  
  30.                    if (method2[i].getName().indexOf("get") == 0) {  
  31.                        get[j] = method2[i];  
  32.                        ++j;  
  33.                    }  
  34.                }  
  35.   
  36.                for (int i = 0; i < get.length; i++) {  
  37.                    if (get[i] == null)// 数组初始化的长度多于get方法,所以数组后面的部分是null  
  38.                        continue;  
  39.                    // 得到get方法的值,判断时候为null,如果为null则进行下一个循环  
  40.                    Object value = get[i].invoke(class2, new Object[] {});  
  41.                    if (null == value)  
  42.                        continue;  
  43.                    // 得到get方法的名称 例如:getXxxx  
  44.                    String getName = get[i].getName();  
  45.                    // 得到set方法的时候传入的参数类型,就是get方法的返回类型  
  46.                    Class<?> paramType = get[i].getReturnType();  
  47.                    Method getMethod = null;  
  48.                    try {  
  49.                        // 判断在class1中时候有class2中的get方法,如果没有则抛异常继续循环  
  50.                        getMethod = clazz1.getMethod(getName, new Class[] {});  
  51.                    } catch (NoSuchMethodException e) {  
  52.                        continue;  
  53.                    }  
  54.                    // class1的get方法不为空并且class1中get方法得到的值为空,进行赋值,如果class1属性原来有值,则跳过  
  55.                    if (null == getMethod || null != getMethod.invoke(class1, new Object[] {}))  
  56.                        continue;  
  57.                    // 通过getName 例如getXxxx 截取后得到Xxxx,然后在前面加上set,就组装成set的方法名  
  58.                    String setName = "set" + getName.substring(3);  
  59.                    // 得到class1的set方法,并调用  
  60.                    Method setMethod = clazz1.getMethod(setName, paramType);  
  61.                    setMethod.invoke(class1, value);  
  62.                }  
  63.            }  
  64.        } catch(Exception e) {  
  65.         System.out.println(e);  
  66.        }  
  67.    }  

推荐使用第二种方法。

 

分享到:
评论

相关推荐

    C#基础知识 基类Object

    - `Equals()`: 检查当前对象是否等于另一个对象。默认实现基于引用相等,但对于值类型,可以重写以实现值的比较。 - `GetHashCode()`: 返回对象的哈希码,常用于哈希表的查找。哈希码应尽可能独特,但重写时需考虑...

    302.300.JAVA基础教程_面向对象(中)-Object类综合练习(302).rar

    默认情况下,它执行的是引用的比较,即如果两个对象是同一个对象,那么结果为`true`。在实际开发中,我们常常需要根据对象的属性来比较,所以会重写`equals()`方法,实现基于对象内容的比较。 3. `hashCode()`方法...

    testBoxingApp.rar

    当一个值类型被装箱时,编译器会在托管堆上创建一个新的Object实例,然后将值类型的数据复制到这个新对象中。这个过程是自动的,不需要程序员显式进行。 例如,当我们将一个int类型的变量转换为Object类型时,实际...

    常用类.docx

    - `public String(String original)`: 将另一个字符串对象转换为新字符串。 - `public int length()`: 返回字符串的长度。 **3.3 字符串的不可变性** - 不可变性意味着字符串一旦被创建,其内容就不能被修改。这是...

    .NET基础面试题三

    - **委托**是一种引用类型,可以将方法作为参数传递给另一个方法。 - **事件**是一种特殊的委托,用于发布和订阅消息,通常用于对象间的通信。 #### 13. Override与Overload的区别 - `Override`表示重写基类的方法...

    ,NET概念问题总结.doc

    .NET 概念问题总结 ... String 类是不可变的,每次修改字符串都会创建新的对象,因此 `string s1 = "abc" + "def"` 会创建一个新对象,而 `string s2 = "abcdef"` 直接使用常量字符串池中的对象,不会创建新对象。

    33条C#、.Net经典面试题目及答案[归纳].pdf

    - 必要条件:互斥(一次只有一个进程使用资源)、占有并等待(已占有的资源并等待其他资源)、无抢占(不能强制夺回资源)、循环等待(存在一个等待链,每个进程都在等待链中的下一个进程所占有的资源)。...

    OC底层原理之OC语法课件ppt

    - 在64位环境下,一个对象占用16个字节,但实际上只使用了8个字节。 - 对象的`isa`指针非常重要,用于指向对象所属的类的信息。 - `instance`对象的`isa`指向`class`对象。 - `class`对象的`isa`指向`meta-class...

    Java面试八股文十万字总结.docx

    当多个线程同时访问一个集合时,如果一个线程修改了集合,而另一个线程正在进行迭代,则抛出`ConcurrentModificationException`异常。 **39. 说说Hashtable 与 HashMap 的区别** - **线程安全性**:`Hashtable`...

    .Net 面试笔试大全-附答案

    - `internal`:内部访问,只限于同一个程序集中的类可以访问。 #### 七、sealed修饰符 `sealed`修饰符用于禁止从被修饰的类派生出其他类。这意味着任何被声明为`sealed`的类都不能作为其他类的基类。此外,`sealed`...

    C#,.Net软件工程师面试题

    - 是一种引用类型,类似于函数指针,可以将方法作为参数传递给另一个方法。 - 可以用于异步编程或事件处理。 - **事件**: - 是一种特殊的委托,用于发布订阅模式。 - 代表了某个对象发生的变化通知。 #### 13...

    asp.net

    - **创建对象**:使用 `new` 关键字创建一个新的类实例,如 `new ClassName()`。这要求类具有可用的构造函数。 - **隐藏继承成员**:在派生类中使用 `new` 关键字来隐藏基类中的虚方法或属性,如 `public new void...

    MSDN_C#编程指南

    - **继承概念**:继承允许一个类(子类)继承另一个类(父类)的属性和方法。 - **多态性**:通过继承实现多态性,使子类能够覆盖或扩展父类的行为。 #### 十六、抽象类、密封类及类成员 - **抽象类**:抽象类不能...

    C#面试题库

    而`StringBuilder`是一个可变的字符串对象,适合于大量字符串操作,因为它避免了频繁创建新字符串对象带来的性能开销。 8. **const和readonly**: `const`是在编译时确定的常量,不能在运行时改变。`readonly`字段...

    Asp.net面试题

    如使用`foreach`循环逐个添加元素,使用`ArrayList.Adapter`方法直接将数组转换,或使用`Copy`方法复制数组到ArrayList。 4. **DataGrid数据源**:DataGrid控件可以绑定到多种数据源,包括DataSet、DataTable、 ...

    Java面试题整理精华

    而`this()`则用于在同一类的不同构造函数之间进行调用,它可以帮助避免代码重复,通过传递不同的参数调用同一类中的另一个构造函数。 #### 2. 作用域public, protected, private,以及不写时的区别? - **public**...

    我的java知识点汇总

    - **继承**:一个类可以继承另一个类的属性和方法,实现代码重用。 - **多态**:允许不同类的对象对同一消息作出响应,提供灵活性。 - **接口**:定义行为规范,类通过实现接口来遵循这些规范。 2. **内存管理**...

    C#、.Net经典面试题

    - `finalize()`(C#中为`~ClassName()`析构函数)是Object类的一个方法,当对象被垃圾回收时,其析构函数将被调用。 #### 9\. HashMap与Hashtable区别 `HashMap`是轻量级的、非线程安全的散列表实现,允许键和值为...

    33条C#、.Net经典面试题目及答案.doc

    - **互斥条件**:至少有一个资源必须处于非共享模式,即一次只有一个进程能够使用该资源。 - **请求与保持条件**:一个进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有。 - **不...

Global site tag (gtag.js) - Google Analytics