Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.azbh111.utils.java.reflect.ObjectUtils Maven / Gradle / Ivy
package com.github.azbh111.utils.java.reflect;
import com.github.azbh111.utils.java.exception.ExceptionUtils;
import com.github.azbh111.utils.java.reflect.model.ClassCopyDesc;
import com.github.azbh111.utils.java.reflect.model.UnsafeField;
import com.github.azbh111.utils.java.unsafe.UnsafeUtils;
import java.io.Console;
import java.lang.annotation.Annotation;
import java.lang.instrument.ClassDefinition;
import java.lang.reflect.*;
import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
/**
* @author zhengyongpan
* @date 2018/7/19 下午2:06
*/
public class ObjectUtils {
// 缓存一些不可变的类
private static final Set unmodifiedClass = ConcurrentHashMap.newKeySet();
private static final Set unmodifiedClassForDeepCopy = ConcurrentHashMap.newKeySet();
private static final Set unmodifiedClassForShallowCopy = ConcurrentHashMap.newKeySet();
private static final Map> unsafeFieldMap = new ConcurrentHashMap<>();
static {
registerUnmodifiedClass(String.class);
registerUnmodifiedClass(Boolean.class);
registerUnmodifiedClass(Character.class);
registerUnmodifiedClass(Byte.class);
registerUnmodifiedClass(Short.class);
registerUnmodifiedClass(Integer.class);
registerUnmodifiedClass(Long.class);
registerUnmodifiedClass(Float.class);
registerUnmodifiedClass(Double.class);
registerUnmodifiedClass(UUID.class);
registerUnmodifiedClass(URL.class);
registerUnmodifiedClass(URI.class);
registerUnmodifiedClass(Class.class);
registerUnmodifiedClass(Field.class);
registerUnmodifiedClass(Constructor.class);
registerUnmodifiedClass(Method.class);
registerUnmodifiedClass(Parameter.class);
registerUnmodifiedClass(ClassDefinition.class);
registerUnmodifiedClass(Console.class);
// ThreadLocal中只有一个hashCode变量,这个值是作为key来取值的,如果进行深拷贝,hashCode不变,应该不影响使用(未测试),所以直接当成不可变类处理
registerUnmodifiedClass(ThreadLocal.class);
}
/**
* 将对象字段名字和值,组装成map
* @param object
* @return
*/
public static Map toMap(Object object) {
return toMap(object, field -> true);
}
/**
* 将对象字段名字和值,组装成map
* @param object
* @return
*/
public static Map toMap(Object object, Predicate filter) {
Map map = new HashMap<>();
if (object == null) {
return map;
}
for (Field field : ReflectUtils.getAllFields(object.getClass(), filter)) {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
if (!field.isAccessible()) {
field.setAccessible(true);
}
try {
map.put(field.getName(), field.get(object));
} catch (IllegalAccessException e) {
ExceptionUtils.throwException(e);
}
}
return map;
}
/**
* 注册不可变的类
* 不可变的类的对象在深拷贝和浅拷贝时,都是直接返回对象自身
*
* @param clazz
*/
public static void registerUnmodifiedClass(Class clazz) {
unmodifiedClassForDeepCopy.add(clazz);
unmodifiedClassForShallowCopy.add(clazz);
}
/**
* 判断一个对象是否是枚举
*
* @param o
* @return
*/
public static boolean isEnum(Object o) {
// Enum不可以被class继承,所以可以直接这样判断
return o instanceof Enum;
}
/**
* 判断一个对象是否是注解
*
* @param o
* @return
*/
public static boolean isAnnotation(Object o) {
// 注解对象实现了Annotation,继承了Proxy,而Proxy的superClass是Object
if (o instanceof Annotation && o instanceof Proxy && o.getClass().getSuperclass().getSuperclass() == Object.class) {
return true;
}
return false;
}
/**
* 深拷贝任意对象
*
* @param s
* @param
* @return
* @throws Throwable
*/
public static T deepCopy(T s) throws InstantiationException {
return deepCopy(new HashMap<>(), s);
}
/**
* 深拷贝任意对象
*
* @param cache 用来处理循环引用 key:拷贝前对象地址,value:对象
* @param s
* @param
* @return
* @throws InstantiationException
*/
private static T deepCopy(Map cache, T s) throws InstantiationException {
if (s == null) {
return null;
}
Class type = s.getClass();
if (type.isArray()) {
Object o = cache.get(UnsafeUtils.getAddress(s));
return o != null ? (T) o : deepCopyArray(cache, s);
}
if (isImmutableForDeepCopy(s)) {
// 不可变的类型直接返回
return s;
}
// 源对象地址
long srcAddr = UnsafeUtils.getAddress(s);
Object o = cache.get(srcAddr);
if (o != null) {
// 如果已经拷贝过了,直接返回,避免循环
return (T) o;
}
ClassCopyDesc copyer = getOrParseUnsafeField(type);
T t = (T) UnsafeUtils.allocateInstance(type);
// 把拷贝出来的对象缓存起来
cache.put(srcAddr, t);
for (UnsafeField unsafeField : copyer.getFields()) {
Class fType = unsafeField.getType();
long offset = unsafeField.getOffset();
// 基础类型直接赋值就行了
if (fType == boolean.class) {
UnsafeUtils.putBoolean(t, offset, UnsafeUtils.getBoolean(s, offset));
} else if (fType == char.class) {
UnsafeUtils.putChar(t, offset, UnsafeUtils.getChar(s, offset));
} else if (fType == byte.class) {
UnsafeUtils.putByte(t, offset, UnsafeUtils.getByte(s, offset));
} else if (fType == short.class) {
UnsafeUtils.putShort(t, offset, UnsafeUtils.getShort(s, offset));
} else if (fType == int.class) {
UnsafeUtils.putInt(t, offset, UnsafeUtils.getInt(s, offset));
} else if (fType == long.class) {
UnsafeUtils.putLong(t, offset, UnsafeUtils.getLong(s, offset));
} else if (fType == float.class) {
UnsafeUtils.putFloat(t, offset, UnsafeUtils.getFloat(s, offset));
} else if (fType == double.class) {
UnsafeUtils.putDouble(t, offset, UnsafeUtils.getDouble(s, offset));
} else {
UnsafeUtils.putObject(t, offset, deepCopy(cache, UnsafeUtils.getObject(s, offset)));
}
}
return t;
}
private static boolean isImmutableForDeepCopy(Object o) {
return o instanceof Class || isEnum(o) || isAnnotation(o) || unmodifiedClass.contains(o.getClass());
}
private static T deepCopyArray(Map cache, T srcArr) throws InstantiationException {
Class component = srcArr.getClass().getComponentType();
int length = Array.getLength(srcArr);
Object targetArr = Array.newInstance(component, length);
if (component.isPrimitive() || component.isEnum() || unmodifiedClass.contains(component)) {
// 基本类型/枚举/不可变类的对象 直接拷贝
System.arraycopy(srcArr, 0, targetArr, 0, length);
} else {
Object o = cache.get(UnsafeUtils.getAddress(srcArr));
if (o != null) {
return (T) o;
}
// 对象拷贝
for (int i = 0; i < length; i++) {
Array.set(targetArr, i, deepCopy(cache, Array.get(srcArr, i)));
}
}
return (T) targetArr;
}
private static ClassCopyDesc getOrParseUnsafeField(Class clazz) {
ClassCopyDesc copyer = (ClassCopyDesc) unsafeFieldMap.get(clazz);
if (copyer == null) {
copyer = ClassCopyDesc.of(clazz);
unsafeFieldMap.put(clazz, copyer);
}
return copyer;
}
}