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

com.github.datalking.util.ClassUtils Maven / Gradle / Ivy

The newest version!
package com.github.datalking.util;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author yaoo on 4/19/18
 */
public abstract class ClassUtils {

    private static final char PACKAGE_SEPARATOR = '.';

    private static final Map, Class> primitiveWrapperTypeMap = new IdentityHashMap<>(8);

    private static final Map, Class> primitiveTypeToWrapperMap = new IdentityHashMap<>(8);


    public static Class[] getAllInterfacesForClass(Class clazz, ClassLoader classLoader) {
        Set> ifcs = getAllInterfacesForClassAsSet(clazz, classLoader);
        return ifcs.toArray(new Class[ifcs.size()]);
    }

    public static Set> getAllInterfacesForClassAsSet(Class clazz) {
        return getAllInterfacesForClassAsSet(clazz, null);
    }

    // 返回clazz类及其超类实现的所有接口
    public static Set> getAllInterfacesForClassAsSet(Class clazz, ClassLoader classLoader) {
        Assert.notNull(clazz, "Class must not be null");

        if (clazz.isInterface() && isVisible(clazz, classLoader)) {
            return Collections.singleton(clazz);
        }

        Set> interfaces = new LinkedHashSet<>();
        while (clazz != null) {
            Class[] ifcs = clazz.getInterfaces();
            for (Class ifc : ifcs) {

                // 递归查询并加入
                interfaces.addAll(getAllInterfacesForClassAsSet(ifc, classLoader));
            }
            clazz = clazz.getSuperclass();
        }

        return interfaces;
    }

    public static boolean isVisible(Class clazz, ClassLoader classLoader) {
        if (classLoader == null) {
            return true;
        }
        try {
            Class actualClass = classLoader.loadClass(clazz.getName());
            return (clazz == actualClass);
        } catch (ClassNotFoundException ex) {
            return false;
        }
    }

    public static boolean isAssignableValue(Class type, Object value) {
        Assert.notNull(type, "Type must not be null");
        return (value != null ? isAssignable(type, value.getClass()) : !type.isPrimitive());
    }

    /**
     * 判断c1是否是c2的父类或父接口
     */
    public static boolean isAssignable(Class c1, Class c2) {
        Assert.notNull(c1, "Left-hand side type must not be null");
        Assert.notNull(c2, "Right-hand side type must not be null");

        if (c1.isAssignableFrom(c2)) {
            return true;
        }

//        if (c1.isPrimitive()) {
//            Class resolvedPrimitive = primitiveWrapperTypeMap.get(c2);
//            if (c1 == resolvedPrimitive) {
//                return true;
//            }
//        } else {
//            Class resolvedWrapper = primitiveTypeToWrapperMap.get(c2);
//            if (resolvedWrapper != null && c1.isAssignableFrom(resolvedWrapper)) {
//                return true;
//            }
//        }
        return false;
    }


    public static Method getMostSpecificMethod(Method method, Class targetClass) {
        if (method != null && isOverridable(method, targetClass) &&
                targetClass != null && targetClass != method.getDeclaringClass()) {
            try {
                if (Modifier.isPublic(method.getModifiers())) {
                    try {
                        return targetClass.getMethod(method.getName(), method.getParameterTypes());
                    } catch (NoSuchMethodException ex) {
                        return method;
                    }
                } else {
                    Method specificMethod = ReflectionUtils.findMethod(targetClass, method.getName(), method.getParameterTypes());
                    return (specificMethod != null ? specificMethod : method);
                }
            } catch (SecurityException ex) {
                // Security settings are disallowing reflective access; fall back to 'method' below.
            }
        }
        return method;
    }

    private static boolean isOverridable(Method method, Class targetClass) {
        if (Modifier.isPrivate(method.getModifiers())) {
            return false;
        }
        if (Modifier.isPublic(method.getModifiers()) || Modifier.isProtected(method.getModifiers())) {
            return true;
        }
        return getPackageName(method.getDeclaringClass()).equals(getPackageName(targetClass));
    }

    public static String getPackageName(Class clazz) {
        Assert.notNull(clazz, "Class must not be null");
        return getPackageName(clazz.getName());
    }

    public static String getPackageName(String fqClassName) {
        Assert.notNull(fqClassName, "Class name must not be null");
        int lastDotIndex = fqClassName.lastIndexOf(PACKAGE_SEPARATOR);
        return (lastDotIndex != -1 ? fqClassName.substring(0, lastDotIndex) : "");
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy