All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gu.sql2java.utils.DeepCloneUtils Maven / Gradle / Ivy

There is a newer version: 5.3.2
Show newest version
package gu.sql2java.utils;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.google.common.base.Throwables;
import com.google.common.primitives.Primitives;

import gu.sql2java.Constant;

import static java.lang.reflect.Modifier.FINAL;
import static java.lang.reflect.Modifier.STATIC;

/**
 * 深度对象克隆工具,copy from common-java
 * @author guyadong
 * @since 3.24.0
 */
public class DeepCloneUtils implements Constant{

	/**
	 * (深度克隆)复制数据对象的所有字段,输入参数为{@code null}返回{@code null}
* 基本数据类型(primitive,String)不做复制,其他类型字段执行{@link #deepClone(Object) }方法深度克隆 * @param input * @param ifVolatile 定义对 volatile 字段的处理方式: *
    *
  • 1 -- 字段设置为{@code null}
  • *
  • 2 -- 执行克隆
  • *
  • 其他 -- 跳过此字段
  • *
* @return always input * @see #deepClone(Object) */ public static T cloneFields(T input, int ifVolatile){ if(noClone(input)){ /** 基本类型不需要复制 */ return input; } for(Class clazz=input.getClass();null != clazz && !Object.class.equals(clazz);clazz = clazz.getSuperclass()) { for(Field field:clazz.getDeclaredFields()) { try { if(((field.getModifiers() & (STATIC+FINAL)) == 0 && !noClone(field.getType())) || FIELD_MODIFIED.equals(field.getName()) || FIELD_INITIALIZED.equals(field.getName())) { field.setAccessible(true); if(!Modifier.isVolatile(field.getModifiers())) { field.set(input, deepClone(field.get(input))); }else if(1 == ifVolatile) { field.set(input, null); }else if(2 == ifVolatile) { field.set(input, deepClone(field.get(input))); } } } catch (IllegalArgumentException | IllegalAccessException e) { Throwables.throwIfUnchecked(e); throw new RuntimeException(e); } } } return input; } /** * (深度克隆)对数据对象的所有字段执行深度复制,输入参数为{@code null}返回{@code null}
* @see #cloneFields(Object, int) */ public static T cloneFields(T input){ return cloneFields(input,2); } /** * [递归]复制数据对象(深度克隆),输入参数为{@code null}返回{@code null}
* 基本数据类型(primitive,String)不做复制,原样返回, * 实现 {@link Cloneable} 接口的对象执行 clone 方法, * {@link Map}和{@link Collection}接口实现如果有默认构造方法执行{@code putAll,addAll}方法完成对象复制, * 如果对象类型有复制构造方法,调用复制构造方法完成对象复制, * 实现 {@link Serializable}接口的对象基于对象的序列化反序列化实现对象复制 * @param input */ @SuppressWarnings("unchecked") public static T deepClone(T input){ if(noClone(input)){ /** 基本类型不需要复制 */ return input; } T cloned; if(input instanceof Collection){ if(input != (cloned = tryConstructContainer(input,Collection.class))){ return cloned; } } if (input instanceof Map) { if(input != (cloned = tryConstructContainer(input,Map.class))){ return cloned; } } if(input instanceof Cloneable){ if(input.getClass().isArray()){ Class componentType = input.getClass().getComponentType(); int length = Array.getLength(input); cloned = (T) Array.newInstance(componentType, length); System.arraycopy(input, 0, cloned, 0, length); if(!noClone(componentType)) { for(int i=0,end_i=Array.getLength(cloned);iT callClone(T input) { try { return (T) input.getClass().getMethod("clone").invoke(input); } catch (Exception e) { Throwables.throwIfUnchecked(e); throw new RuntimeException(e); } } private static boolean noClone(Object object){ if(null == object){ return true; } return noClone(object.getClass()); } private static boolean noClone(Class clazz){ if(Primitives.unwrap(clazz).isPrimitive()){ return true; } if(String.class.equals(clazz)){ return true; } return false; } /** * {@link Map},{@link Collection}类型,如果有默认构造方法使用{@code putAll,addAll}方法完成对象复制 * @param input * @param targetType */ @SuppressWarnings({ "rawtypes", "unchecked" }) private static T tryConstructContainer(T input,ClasstargetType){ if(targetType.isInstance(input)){ try{ Object output ; if(input instanceof Map || input instanceof Collection){ output = input.getClass().getConstructor().newInstance(); if(output instanceof Map){ Set entrySet = ((Map)input).entrySet(); for(Entry entry:entrySet) { ((Map)output).put(entry.getKey(), deepClone(entry.getValue())); } return (T) output; }else if(output instanceof Collection){ for(Object element:(Collection)input) { ((Collection)output).add(deepClone(element)); } return (T) output; } } } catch (Exception e) { Throwables.throwIfUnchecked(e); throw new RuntimeException(e); } } return input; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy