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

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;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy