com.iqiny.silly.common.util.SillyReflectUtil Maven / Gradle / Ivy
The newest version!
/*
* Copyright iqiny.com
*
* https://gitee.com/iqiny/silly
*
* project name:silly-common
* project description:top silly project pom.xml file
*/
package com.iqiny.silly.common.util;
import com.iqiny.silly.common.exception.SillyException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.*;
import java.util.function.Function;
public abstract class SillyReflectUtil {
private final static Log logger = LogFactory.getLog(SillyReflectUtil.class);
/**
* Suffix for array class names: "[]"
*/
public static final String ARRAY_SUFFIX = "[]";
/**
* Prefix for internal array class names: "["
*/
private static final String INTERNAL_ARRAY_PREFIX = "[";
/**
* Prefix for internal non-primitive array class names: "[L"
*/
private static final String NON_PRIMITIVE_ARRAY_PREFIX = "[L";
/**
* The package separator character: '.'
*/
private static final char PACKAGE_SEPARATOR = '.';
/**
* The path separator character: '/'
*/
private static final char PATH_SEPARATOR = '/';
/**
* The inner class separator character: '$'
*/
private static final char INNER_CLASS_SEPARATOR = '$';
/**
* The CGLIB class separator: "$$"
*/
public static final String CGLIB_CLASS_SEPARATOR = "$$";
/**
* The ".class" file suffix
*/
public static final String CLASS_FILE_SUFFIX = ".class";
public static M newInstance(Class> clazz, Object... initargs) {
M m = null;
Exception ex = null;
try {
Constructor>[] constructors = clazz.getConstructors();
for (Constructor> constructor : constructors) {
try {
m = (M) constructor.newInstance(initargs);
} catch (Exception ignore) {
ex = ignore;
}
}
} catch (Exception e) {
ex = e;
}
if (m == null && ex != null) {
throw SillyException.newInstance("实例化对象失败!类:" + clazz.getName() + " 信息:" + ex.getMessage(), ex);
}
return m;
}
public static > C classForName(String className) {
try {
return (C) forName(className, null);
} catch (Exception e) {
throw SillyException.newInstance("class 获取异常" + className + e.getMessage(), e);
}
}
/**
* 参考Spring ClassUtils
*/
public static Class> forName(String name, ClassLoader classLoader) throws ClassNotFoundException, LinkageError {
SillyAssert.notNull(name, "Name must not be null");
// "java.lang.String[]" style arrays
if (name.endsWith(ARRAY_SUFFIX)) {
String elementClassName = name.substring(0, name.length() - ARRAY_SUFFIX.length());
Class> elementClass = forName(elementClassName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
}
// "[Ljava.lang.String;" style arrays
if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(";")) {
String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1);
Class> elementClass = forName(elementName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
}
// "[[I" or "[[Ljava.lang.String;" style arrays
if (name.startsWith(INTERNAL_ARRAY_PREFIX)) {
String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length());
Class> elementClass = forName(elementName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
}
ClassLoader clToUse = classLoader;
if (clToUse == null) {
clToUse = getDefaultClassLoader();
}
try {
return (clToUse != null ? clToUse.loadClass(name) : Class.forName(name));
} catch (ClassNotFoundException ex) {
int lastDotIndex = name.lastIndexOf(PACKAGE_SEPARATOR);
if (lastDotIndex != -1) {
String innerClassName =
name.substring(0, lastDotIndex) + INNER_CLASS_SEPARATOR + name.substring(lastDotIndex + 1);
try {
return (clToUse != null ? clToUse.loadClass(innerClassName) : Class.forName(innerClassName));
} catch (ClassNotFoundException ex2) {
// Swallow - let original exception get through
}
}
throw ex;
}
}
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back...
}
if (cl == null) {
// No thread context class loader -> use class loader of this class.
cl = SillyReflectUtil.class.getClassLoader();
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
try {
cl = ClassLoader.getSystemClassLoader();
} catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
}
}
}
return cl;
}
public static M newInstance(String className, Object... initargs) {
try {
Class clazz = (Class) Class.forName(className);
return newInstance(clazz, initargs);
} catch (Exception e) {
throw SillyException.newInstance("实例化对象失败!" + e.getMessage(), e);
}
}
public static void makeAccessible(Constructor> ctor) {
if ((!Modifier.isPublic(ctor.getModifiers()) ||
!Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) && !ctor.isAccessible()) {
ctor.setAccessible(true);
}
}
/**
* 序列化克隆对象(深克隆)
*/
public static M serializeCloneObj(M serializable) {
ByteArrayInputStream in = null;
ObjectInputStream ois = null;
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
) {
oos.writeObject(serializable);
in = new ByteArrayInputStream(out.toByteArray());
ois = new ObjectInputStream(in);
return (M) ois.readObject();
} catch (Exception e) {
throw new SillyException("序列化克隆对象错误" + e.getMessage(), e);
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException ignore) {
}
}
if (in != null) {
try {
in.close();
} catch (IOException ignore) {
}
}
}
}
/**
* copyright com.baomidou.mybatisplus.core.toolkit.getSuperClassGenericType
*/
public static > T getSuperClassGenericType(final Class> clazz, final int index) {
Type genType = clazz.getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
logger.warn(String.format("Warn: %s's superclass not ParameterizedType", clazz.getSimpleName()));
return (T) Object.class;
} else {
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index < params.length && index >= 0) {
if (!(params[index] instanceof Class)) {
logger.warn(String.format("Warn: %s not set the actual class on superclass generic parameter", clazz.getSimpleName()));
return (T) Object.class;
} else {
return (T) params[index];
}
} else {
logger.warn(String.format("Warn: Index: %s, Size of %s's Parameterized Type: %s .", index, clazz.getSimpleName(), params.length));
return (T) Object.class;
}
}
}
/**
* 获取往上查找父类第一个遇到的泛型类类型
*/
public static > T getAllSuperClassGenericType(final Class> clazz, final int index) {
Class> currentClass = clazz;
while (currentClass != Object.class) {
final Class> superClassGenericType = getSuperClassGenericType(currentClass, index);
if (superClassGenericType != Object.class) {
return (T) superClassGenericType;
}
currentClass = currentClass.getSuperclass();
}
return (T) Object.class;
}
/**
* 获取往上查找父类第一个遇到的泛型类类型
*/
public static > T getSuperClassGenericType(final Class> startClazz, final Class> targetClazz, final int index) {
Class> currentClass = startClazz;
while (currentClass != Object.class) {
if (currentClass.getSuperclass().equals(targetClazz)) {
final Class> superClassGenericType = getSuperClassGenericType(currentClass, index);
return (T) superClassGenericType;
}
currentClass = currentClass.getSuperclass();
}
return (T) Object.class;
}
/**
* 获取类下全部的属性
*/
public static List getAllFields(final Class> clazz) {
SillyAssert.notNull(clazz, "获取属性的Class不可为空");
final List fieldList = new ArrayList<>();
Class> currentClass = clazz;
while (currentClass != Object.class) {
final Field[] declaredFields = currentClass.getDeclaredFields();
Collections.addAll(fieldList, declaredFields);
currentClass = currentClass.getSuperclass();
}
return fieldList;
}
/**
* 获取类下全部被特定注解标记的注解
*/
public static List getFieldAnnotations(final Class> clazz, Class annotationClass, Function func) {
SillyAssert.notNull(annotationClass, "标记的annotation不可为空");
final List allFieldList = getAllFields(clazz);
List fieldAnnotationsList = new ArrayList<>();
for (Field field : allFieldList) {
if (field.isAnnotationPresent(annotationClass)) {
final T annotation = func.apply(field);
fieldAnnotationsList.add(annotation);
}
}
return fieldAnnotationsList;
}
/**
* 获取类下全部被特定注解标记的的属性
*/
public static List getFields(final Class> clazz, Class annotationClass) {
SillyAssert.notNull(annotationClass, "标记的annotation不可为空");
final List allFieldList = getAllFields(clazz);
List fieldList = new ArrayList<>();
for (Field field : allFieldList) {
if (field.isAnnotationPresent(annotationClass)) {
fieldList.add(field);
}
}
return fieldList;
}
/**
* 获取字段值
*/
public static Object getFieldValue(Object entity, String fieldName) {
Class> cls = entity.getClass();
Map fieldMaps = getFieldMap(cls);
try {
Field field = fieldMaps.get(fieldName);
SillyAssert.notNull(field, "此类" + cls.getSimpleName() + "参数" + fieldName + "无法获取");
field.setAccessible(true);
return field.get(entity);
} catch (ReflectiveOperationException e) {
throw SillyException.newInstance(e.getMessage());
}
}
/**
* 获取该类的所有属性列表
*/
public static Map getFieldMap(Class> clazz) {
List fieldList = getAllFields(clazz);
Map fieldMap = new HashMap<>(fieldList.size());
for (Field field : fieldList) {
fieldMap.put(field.getName(), field);
}
return fieldMap;
}
}