com.github.azbh111.utils.java.reflect.ObjectUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils-java Show documentation
Show all versions of utils-java Show documentation
com.github.azbh111:utils-java
The newest version!
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.*;
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() != null
&& 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 IdentityHashMap<>(), s);
}
/**
* 深拷贝任意对象
*
* @param cache 用来处理循环引用 key:拷贝前对象,value:对象
* @param s
* @param
* @return
* @throws InstantiationException
*/
private static T deepCopy(Map