`
Gavin.Chen
  • 浏览: 324865 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

JAVA范型与反射结合应用攻略之一ValueCopyUtil

阅读更多

      在进行企业应用的开发过程中,我们经常会遇到原因而必须要从一个对象中拷贝值到另一个对象中,这两个对象有部份相同的字段,必须将这些相同字段的值从源对象拷贝到目标对象中,因此,一个值拷贝的实用类就变得很必要了,下面我们就用JAVA范型与JAVA影射去实现这样一个实用类吧,也算是JAVA范型的一个应用实例了,同时也是一个JAVA影身的简单应用实例。

package common;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 *
 * @author Dao
 */
public class ValueCopyUtil
{

  public static <T> T copyValue(T sourceObject)
  {
    return (T) copyValue(sourceObject, sourceObject.getClass());
  }

  public static <T> T copyValue(Object sourceObject, Class<T> targetObjectClass)
  {
    return copyValue(sourceObject, targetObjectClass, null);
  }

  public static <T> T copyValue(Object sourceObject, Class<T> targetObjectClass, HashMap classMap)
  {
    try
    {
      Object targetObject = targetObjectClass.newInstance();

      return (T) copyValue(sourceObject, targetObject, classMap);
    }
    catch (Exception e)
    {
      return null;
    }
  }

  public static <T> T copyValue(Object sourceObject, Object targetObject, HashMap classMap)
  {
    Class sourceObjectClass = sourceObject.getClass();
    Class targetObjectClass = targetObject.getClass();

    List<String> sourceClassFieldNameList = getClassFieldNameList(sourceObjectClass);
    List<String> targetClassFieldNameList = getClassFieldNameList(targetObjectClass);
    List<String> fieldNameList = getSameFieldNameList(sourceClassFieldNameList, targetClassFieldNameList);

    try
    {
      for (String fieldName : fieldNameList)
      {
        Field sourceField = sourceObjectClass.getDeclaredField(fieldName);
        Field targetField = targetObjectClass.getDeclaredField(fieldName);

        Class sourceFieldType = sourceField.getType();
        Class targetFieldType = targetField.getType();

        if (sourceFieldType == targetFieldType)
        {
          sourceField.setAccessible(true);
          targetField.setAccessible(true);

          Object sourceValue = sourceField.get(sourceObject);

          if (sourceValue != null)
          {
            if (isSimpleType(sourceFieldType))
            {
              targetField.set(targetObject, sourceValue);
            }
            else
            {
              Object copiedObject = copyComplicatedType(sourceValue, classMap);

              targetField.set(targetObject, copiedObject);
            }
          }
        }
      }

      return (T) targetObject;
    }
    catch (Exception e)
    {
      return null;
    }
  }

  private static List<String> getClassFieldNameList(Class cla)
  {
    Field[] fields = cla.getDeclaredFields();
    List<String> fieldNameList = new ArrayList();

    for (int i = 0; i < fields.length; i++)
    {
      Field field = fields[i];
      String fieldName = field.getName();

      fieldNameList.add(fieldName);
    }

    return fieldNameList;
  }

  private static List<String> getSameFieldNameList(List<String> sourceList, List<String> targetList)
  {
    List<String> resultList = new ArrayList();

    for (String source : sourceList)
    {
      for (String target : targetList)
      {
        if (source.equals(target))
        {
          resultList.add(source);
        }
      }
    }

    return resultList;
  }

  private static boolean isSimpleType(Class cla)
  {
    if (cla.isPrimitive())
    {
      return true;
    }

    if (cla == Date.class)
    {
      return true;
    }

    return false;
  }

  private static Object copyComplicatedType(Object sourceObject, HashMap classMap)
  {
//    System.out.println("========= copyComplicatedType =========");
    Class sourceClass = sourceObject.getClass();

    if (sourceClass.isArray())
    {
      return copyArray(sourceObject, classMap);
    }
    else if (sourceObject instanceof List)
    {
      return copyList(sourceObject, classMap);
    }
    else if (sourceObject instanceof Map)
    {
      return copyMap(sourceObject, classMap);
    }

    return copySubObject(sourceObject, classMap);
  }

  private static Object copySubObject(Object subSourceObject, HashMap classMap)
  {
//    System.out.println("========= copySubobject =========");
    Object mapClassObject = classMap.get(subSourceObject.getClass());

    if (mapClassObject != null)
    {
      Class mapClass = (Class) mapClassObject;

      Object subTargetObject = copyValue(subSourceObject, mapClass, classMap);

      return subTargetObject;
    }

    return subSourceObject;
  }

  private static Object copyArray(Object sourceObjectArray, HashMap classMap)
  {
//    System.out.println("========= copyArray =========");
    int arraySize = Array.getLength(sourceObjectArray);
    if (arraySize > 0)
    {
      Object testObject = Array.get(sourceObjectArray, 0);
      Object targetObjectArray = Array.newInstance(testObject.getClass(), arraySize);

      for (int i = 0; i < arraySize; i++)
      {
        Object subSourceObject = Array.get(sourceObjectArray, i);
        Object subTargetObject = copySubObject(subSourceObject, classMap);

        Array.set(targetObjectArray, i, subTargetObject);
      }
    }

    return sourceObjectArray;
  }

  private static Object copyMap(Object sourceObject, HashMap classMap)
  {
//    System.out.println("========= copyMap =========");
    try
    {
      Class sourceObjectClass = sourceObject.getClass();
      Map targetObjectMap = (Map) sourceObjectClass.newInstance();
      Map sourceObjectMap = (Map) sourceObject;

      Set set = sourceObjectMap.entrySet();
      Iterator<Entry> iterator = set.iterator();
      while (iterator.hasNext())
      {
        Entry sourceEntry = iterator.next();

        Object subSourceObject = sourceEntry.getValue();
        Object subTargetObject = copySubObject(subSourceObject, classMap);

        targetObjectMap.put(sourceEntry.getKey(), subTargetObject);
      }

      return targetObjectMap;
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return sourceObject;
  }

  private static Object copyList(Object sourceObject, HashMap classMap)
  {
//    System.out.println("========= copyList =========");
    try
    {
      Class sourceObjectClass = sourceObject.getClass();
      List targetObjectList = (List) sourceObjectClass.newInstance();
      List sourceObjectList = (List) sourceObject;

      for (Object subObject : sourceObjectList)
      {
        Object subTargetObject = copySubObject(subObject, classMap);

        targetObjectList.add(subTargetObject);
      }

      return targetObjectList;
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return sourceObject;
  }
}

 

分享到:
评论

相关推荐

    Java 范型Java 范型.doc

    Java 范型Java 范型

    Java 范型攻略篇

    ### Java范型攻略篇:深度解析与应用 #### 一、引言:Java范型的引入 在Java的发展历程中,范型(Generics)的引入标志着语言设计上的一个重要里程碑。自Java 1.5发布以来,范型成为了Java语言的重要特性之一,极...

    C++ 设计新思维:范型编程与设计模式之应用.pdf

    C++ 设计新思维 范型编程与设计模式之应用 pdf

    JAVA范型指南中文版

    Java 泛型是一种在编程中实现强类型检查和减少冗余类型转换的机制,它是在JDK 1.5版本中引入的。泛型的主要目标是提高代码的类型安全性、可读性和重用性,避免在...理解和熟练掌握泛型是每个Java开发者必备的技能之一。

    范型编程与设计模式之应用

    《C++设计新思维:范型编程与设计模式之应用》一书深入剖析了范型编程这一核心概念,以及在C++语言中的具体应用。范型编程,也称为泛型编程,是C++中的一项重要特性,它允许程序员编写不依赖特定数据类型的代码,...

    C++ 设计新思维:范型编程与设计模式之应用

    《C++ 设计新思维:范型编程与设计模式之应用》是一本深入探讨C++编程技巧和设计理念的专业书籍,特别关注了范型编程和设计模式在实际开发中的应用。这本书旨在帮助读者提升C++编程的灵活性、可重用性和效率,通过...

    C++ 设计新思维:范型编程与设计模式之应用(中文PDF)

    并且通过运用这些模板技术(例如元编程等),实现了多个设计模式的代码框架的自动生成,书不厚,正文内容不过300页,但是书中没有废话,每一章的内容都很精彩,值得仔细推敲和研究,虽然里面有少量错误(有些可能是...

    java范型[参照].pdf

    Java泛型是Java 5版本引入的一个重要特性,极大地增强了代码的类型安全性和可读性。泛型允许我们在编写代码时指定容器(如List、Set、Map等集合类)能够存储的数据类型,从而避免了不必要的类型转换,并在编译时期就...

    java范型[参考].pdf

    Java泛型是Java 5版本引入的一个重要特性,极大地增强了代码的类型安全性和效率。泛型允许我们在编写类、接口和方法时指定一种或多种类型参数,使得代码能够处理多种不同类型的对象,同时在编译时进行严格的类型检查...

    c++ 设计新思维:范型编程与设计模式之应用

    《C++ 设计新思维:范型编程与设计模式之应用》是一本深入探讨C++编程技巧和设计理念的专业书籍。本书旨在帮助读者理解和掌握C++中的范型编程(Generic Programming)以及设计模式(Design Patterns)的应用,从而...

    Java 泛型(Generics)使用说明

    在实际应用中,如果能够灵活应用范型和反射,那么该Java程序员可以设计出非常好的东西来,从而解决实际开发简化开发过程的目的。比如,在EJB 2.0开发客户端应用时,如果使用范型和反射,可以把EJB 2.0的标准使用...

    设计新思维:范型编程与设计模式之应用(中文版)

    《设计新思维:范型编程与设计模式之应用》是一本深入探讨C++编程思想的著作,由Andrei Alexandrescu撰写,旨在帮助开发者更好地理解和应用范型编程以及设计模式。这本书是C++领域的经典之作,它将抽象的理论与实践...

    论文研究-消息传递范型与C/S范型双范型的主数据管理机制 .pdf

    在实际应用中,消息队列和锁机制的结合为MDM提供了一个可靠且灵活的数据同步解决方案。 主数据管理机制的提出和应用,不仅可以解决企业主数据一致性的问题,还能提高企业的运营效率和竞争力,为企业在激烈的市场...

    C++ 设计新思维:范型编程与设计模式之应用2

    总的来说,《C++ 设计新思维:范型编程与设计模式之应用2》是一本深度探讨C++高级特性的书籍,它帮助读者理解并掌握如何利用范型编程和设计模式来提升C++代码的质量和可维护性,对于想要深入学习C++的开发者来说是一...

    范型程序设计与 STL.pdf

    《范型程序设计与 STL》是一本深入探讨C++编程中的关键概念和技术的书籍,主要聚焦于范型(Generic Programming)和标准模板库(Standard Template Library,简称STL)。范型编程是一种强大的软件开发方法,它允许...

    用Java Socket实现一个简单的基于P2P范型的即时聊天系统。

    在本文中,我们将深入探讨如何使用Java的Socket编程来实现一个简单的基于P2P(Peer-to-Peer)范型的即时聊天系统。P2P网络架构允许每个节点既是客户端也是服务器,这种模式使得数据传输更加分散,提高了系统的可扩展...

Global site tag (gtag.js) - Google Analytics