关闭

java反射(3):反射机制

标签: java反射机制反射reflection
950人阅读 评论(0) 收藏 举报
分类:

第0章:简介


第1章:反射工具类

反射工具类ReflectionUtils.java如下:

package com.lsl.core.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.AccessControlException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 反射工具类
 * @author <a href="mailto:417877417@qq.com">menergy</a>
 * @version 2013-11-12
 */
public abstract class ReflectionUtils {
    
    private static final Pattern CGLIB_RENAMED_METHOD_PATTERN = Pattern.compile("CGLIB\\$(.+)\\$\\d+");
    
/////////////////////////////////////////////////字段反射///////////////////////////////////////////////////////
    
    /**
     * 设置字段为可访问
     *
     * @param field
     */
    public static void makeAccessible(Field field) {
        if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) ||
                Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) {
            field.setAccessible(true);
        }
    }
    
    /**
     * 判断字段是否是公共静态常量("public static final")
     *
     * @param field
     * @return
     */
    public static boolean isPublicStaticFinal(Field field) {
        int modifiers = field.getModifiers();
        return (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers));
    }
    
    /**
     * 是否有指定的公共成员字段(不包括父类)
     *
     * @param clazz
     * @param fieldName
     * @return
     */
    public static boolean hasPublicField(Class<?> clazz, String fieldName){
        return (findPublicField(clazz, fieldName) != null);
    }
    
    /**
     * 是否有指定的声明成员字段(不包括父类)
     *
     * @param clazz
     * @param fieldName
     * @return
     */
    public static boolean hasDeclaredField(Class<?> clazz, String fieldName){
        return (findDeclaredField(clazz, fieldName) != null);
    }
    
    /**
     * 获得类中的所有公共字段(不包括父类)
     *
     * @param clazz
     * @return
     */
    public static Field[] getAllPublicField(Class<?> clazz){
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        return clazz.getFields();
    }
    
    /**
     * 获得对象的所有公共字段(包括父类)
     *
     * @param instance
     * @return
     */
    public static Map<String, Field> getAllPublicFieldIncludeParents(Class<?> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException("clazz must not be null");
        }
        Map<String, Field> fieldMap = new HashMap<String, Field>();
        for (Class<?> superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
            Field[] fields = superClass.getFields();
            for (Field field : fields)
                fieldMap.put(field.getName(), field);
        }
        return fieldMap;
    }
    
    /**
     * 获得类的所有声明字段(不包括父类)
     *
     * @param clazz
     * @return
     */
    public static Field[] getAllDeclaredField(Class<?> clazz){
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        return clazz.getDeclaredFields();
    }
    
    /**
     * 获得对象的所有声明字段(包括父类)
     *
     * @param instance
     * @return
     */
    public static Map<String, Field> getAllDeclaredFieldIncludeParents(Class<?> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException("clazz must not be null");
        }
        Map<String, Field> fieldMap = new HashMap<String, Field>();
        for (Class<?> superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
            Field[] fields = superClass.getDeclaredFields();
            for (Field field : fields)
                fieldMap.put(field.getName(), field);
        }
        return fieldMap;
    }
    
    /**
     * 查找类中的指定公共字段(不包括父类)
     * @param clazz
     * @param fieldName
     * @return
     */
    public static Field findPublicField(Class<?> clazz, String fieldName) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (fieldName == null) {
            throw new IllegalArgumentException("fieldName must not be null");
        }
        try {
            return clazz.getField(fieldName);
        } catch (NoSuchFieldException e) {
            return null;
        }    
    }
    
    /**
     * 查找类中的所有字段(不包括父类)
     *
     * @param clazz
     * @param fieldName
     * @return
     */
    public static Field findDeclaredField(Class<?> clazz, String fieldName) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (fieldName == null) {
            throw new IllegalArgumentException("fieldName must not be null");
        }
        try {
            return clazz.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            return null;
        }    
    }
    
    /**
     * 查找类中的所有字段(包括父类)
     *
     * @param clazz 反射类
     * @param fieldName 字段名
     * @param type 字段类型
     * @return
     */
    public static Field findField(Class<?> clazz, String fileName, Class<?> type) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (fileName == null && type == null) {
            throw new IllegalArgumentException("Either name or type of the field must be specified");
        }
        Class<?> searchType = clazz;
        while (!Object.class.equals(searchType) && searchType != null) {
            Field[] fields = searchType.getDeclaredFields();
            for (Field field : fields) {
                if ((fileName == null || fileName.equals(field.getName())) && (type == null || type.equals(field.getType()))) {
                    return field;
                }
            }
            searchType = searchType.getSuperclass();
        }
        return null;
    }
    
    /**
     * 查找类中的所有字段(包括父类)
     *
     * @param clazz 反射类
     * @param fieldName 字段名
     * @return
     */
    public static Field findField(Class<?> clazz, String fieldName) {
        return findField(clazz, fieldName, null);
    }
    
    /**
     * 查找类中的字段(包括父类),并设置为可访问
     *
     * @param clazz 反射类
     * @param fieldName 字段名
     * @param type
     * @return
     */
    public static Field findFieldBySetAccessible(Class<?> clazz, String fieldName, Class<?> type) {
        Field filed = findField(clazz, fieldName,type);
        if(filed != null){
            //设置字段为可访问
            makeAccessible(filed);
        }
        return null;
    }
    
    /**
     * 查找类中的字段(包括父类),并设置为可访问
     *
     * @param clazz 反射类
     * @param fieldName 字段名
     * @return
     */
    public static Field findFieldBySetAccessible(Class<?> clazz, String fieldName) {
        Field filed = findField(clazz, fieldName);
        if(filed != null){
            //设置字段为可访问
            makeAccessible(filed);
        }
        return null;
    }
    
    /**
     * 查找类中的字段(包括父类),并设置为可访问
     *
     * @param obj 反射对象
     * @param fieldName 字段名
     * @return
     */
    public static Field findFieldBySetAccessible(Object target, String fieldName, Class<?> type) {
        if (target == null) {
            throw new IllegalArgumentException("object must not be null");
        }
        if (fieldName == null || "".equals(fieldName.trim())) {
            throw new IllegalArgumentException("fieldName must not be null or empty");
        }
        findFieldBySetAccessible(target.getClass(), fieldName, type);
        return null;
    }
    
    
    /**
     * 查找类中的字段(包括父类),并设置为可访问
     *
     * @param obj 反射对象
     * @param fieldName 字段名
     * @return
     */
    public static Field findFieldBySetAccessible(Object target, String fieldName) {
        if (target == null) {
            throw new IllegalArgumentException("object must not be null");
        }
        if (fieldName == null || "".equals(fieldName.trim())) {
            throw new IllegalArgumentException("fieldName must not be null or empty");
        }
        findFieldBySetAccessible(target.getClass(), fieldName);
        return null;
    }
    
    /**
     * 获取对象的字段值
     *
     * @param field
     * @param target 应该修改其字段的对象(该field所在的对象)
     * @return
     */
    public static Object getFieldValue(Object target, Field field) {
        try {
            return field.get(target);
        }
        catch (IllegalAccessException ex) {
            handleReflectionException(ex);
            throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage());
        }
    }
    
    /**
     * 直接读取对象字段值, 无视private/protected修饰符, 不经过getter函数
     *
     * @param target 应该修改其字段的对象(该field所在的对象)
     * @param fieldName 字段名
     * @return
     */
    public static Object getFieldValueBySetAccessible(Object target, String fieldName) {
        Field field = findFieldBySetAccessible(target, fieldName);

        if (field == null) {
            throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + target + "]");
        }

        Object result = null;
        try {
            result = field.get(target);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return result;
    }
    
    /**
     * 将Field 对象表示的字段设置为指定的新值
     *
     * @param target 应该修改其字段的对象(该field所在的对象)
     * @param field 字段
     * @param value 正被修改的 target 的字段的新值
     */
    public static void setFieldValue(Object target, Field field, Object value) {
        try {
            field.set(target, value);
        }
        catch (IllegalAccessException ex) {
            handleReflectionException(ex);
            throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": "
                    + ex.getMessage());
        }
    }

    /**
     * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数
     *
     * @param obj 应该修改其字段的对象(该field所在的对象)
     * @param fieldName 字段名
     * @param value 正被修改的 target 的字段的新值
     */
    public static void setFieldValueBySetAccessible(Object obj, String fieldName, Object value) {
        Field field = findFieldBySetAccessible(obj, fieldName);
        if (field == null) {
            throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
        }
        try {
            field.set(obj, value);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    
    /**
     *  处理字段(回调方式,含过滤器)
     *
     * @param clazz 目标类
     * @param fieldCallback 字段处理回调
     * @param fieldFilter 字段过滤回调
     * @throws IllegalArgumentException
     */
    public static void doWithFields(Class<?> clazz, FieldCallback fieldCallback, FieldFilter fieldFilter)
            throws IllegalArgumentException {

        // Keep backing up the inheritance hierarchy.
        Class<?> targetClass = clazz;
        do {
            Field[] fields = targetClass.getDeclaredFields();
            for (Field field : fields) {
                // Skip static and final fields.
                if (fieldFilter != null && !fieldFilter.matches(field)) {
                    continue;
                }
                try {
                    fieldCallback.doWith(field);
                }
                catch (IllegalAccessException ex) {
                    throw new IllegalStateException(
                            "Shouldn't be illegal to access field '" + field.getName() + "': " + ex);
                }
            }
            targetClass = targetClass.getSuperclass();
        }
        while (targetClass != null && targetClass != Object.class);
    }
    
    /**
     *  处理字段(回调方式,不含过滤器)
     *
     * @param clazz
     * @param fc
     * @throws IllegalArgumentException
     */
    public static void doWithFields(Class<?> clazz, FieldCallback fieldCallback) throws IllegalArgumentException {
        doWithFields(clazz, fieldCallback, null);
    }
    
    
    
    /**
     * 字段处理回调方法
     *
     * @author <a href="mailto:417877417@qq.com">menergy</a>
     * @version 2013-11-12
     */
    public interface FieldCallback {
        void doWith(Field field) throws IllegalArgumentException, IllegalAccessException;
    }


    /**
     * 字段过滤回调接口
     *
     * @author <a href="mailto:417877417@qq.com">menergy</a>
     * @version 2013-11-12
     */
    public interface FieldFilter {
        boolean matches(Field field);
    }
    
    /**
     * 匹配所有非static且非final修饰的字段,即非静态常量字段
     */
    public static FieldFilter COPYABLE_FIELDS = new FieldFilter() {
        public boolean matches(Field field) {
            return !(Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers()));
        }
    };

    /**
     * 从源对象复制字段到目标对象中,包括继承的字段,源对象和目标对象必须同一类实例或父子关系
     *
     * @param src
     * @param dest
     * @throws IllegalArgumentException
     */
    public static void copyFieldFromSrcToDest(final Object src, final Object dest) throws IllegalArgumentException {
        if (src == null) {
            throw new IllegalArgumentException("Source for field copy cannot be null");
        }
        if (dest == null) {
            throw new IllegalArgumentException("Destination for field copy cannot be null");
        }
        if (!src.getClass().isAssignableFrom(dest.getClass())) {
            throw new IllegalArgumentException("Destination class [" + dest.getClass().getName()
                    + "] must be same or subclass as source class [" + src.getClass().getName() + "]");
        }
        doWithFields(src.getClass(), new FieldCallback() {
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                makeAccessible(field);
                Object srcValue = field.get(src);
                field.set(dest, srcValue);
            }
        }, COPYABLE_FIELDS);
    }
    
    
    
/////////////////////////////////////////////////方法反射///////////////////////////////////////////////////////
    
    /**
     * 设置方法为可访问
     *
     * @param method
     */
    public static void makeAccessible(Method method) {
        if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
                && !method.isAccessible()) {
            method.setAccessible(true);
        }
    }
    
    /**
     * 获取静态方法(不包括父类)
     *
     * @param clazz
     * @param methodName
     * @param args
     * @return
     */
    public static Method getStaticMethod(Class<?> clazz, String methodName, Class<?>... args) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (methodName == null) {
            throw new IllegalArgumentException("Method name must not be null");
        }
        try {
            Method method = clazz.getMethod(methodName, args);
            return Modifier.isStatic(method.getModifiers()) ? method : null;
        }
        catch (NoSuchMethodException ex) {
            return null;
        }
    }
    
    /**
     * 是否有指定的公共方法(不包括父类)
     *
     * @param clazz
     * @param methodName
     * @param paramTypes
     * @return
     */
    public static boolean hasPublicMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
        return (findPublicMethod(clazz, methodName, paramTypes) != null);
    }
    
    /**
     * 是否有指定的声明方法(不包括父类)
     *
     * @param clazz
     * @param methodName
     * @param paramTypes
     * @return
     */
    public static boolean hasDeclaredMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
        return (findDeclaredMethod(clazz, methodName, paramTypes) != null);
    }
    

    
    /**
     *  获取所有指定的公共成员方法(不包括父类)
     *
     * @param clazz
     * @return
     */
    public static Method[] getAllPublicMethod(Class<?> clazz){
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        return clazz.getMethods();
    }
    
    /**
     * 获取所有声明的成员方法(不包括父类)
     *
     * @param clazz
     * @return
     */
    public static Method[] getAllDeclaredMethod(Class<?> clazz){
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        return clazz.getMethods();
    }
    
    /**
     *获取类中所有声明的成员方法(包括父类)
     *
     * @param leafClass
     * @return
     * @throws IllegalArgumentException
     */
    public static Method[] getAllDeclaredMethodIncludeParents(Class<?> leafClass) throws IllegalArgumentException {
        final List<Method> methods = new ArrayList<Method>(32);
        doWithMethods(leafClass, new MethodCallback() {
            public void doWith(Method method) {
                methods.add(method);
            }
        });
        return methods.toArray(new Method[methods.size()]);
    }
    
    
    /**
     * 获取给定方法名对应的方法数量(包括不同参数方法,父类或接口中的方法)
     *
     * @param clazz
     * @param methodName
     * @return
     */
    public static int getCountOfMethodName(Class<?> clazz, String methodName) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (methodName == null) {
            throw new IllegalArgumentException("Method name must not be null");
        }
        int count = 0;
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method method : declaredMethods) {
            if (methodName.equals(method.getName())) {
                count++;
            }
        }
        Class<?>[] ifcs = clazz.getInterfaces();
        for (Class<?> ifc : ifcs) {
            count += getCountOfMethodName(ifc, methodName);
        }
        if (clazz.getSuperclass() != null) {
            count += getCountOfMethodName(clazz.getSuperclass(), methodName);
        }
        return count;
    }
    
    /**
     * 是否有至少一个包含指定名称的方法(包括父类)
     *
     * @param clazz
     * @param methodName
     * @return
     */
    public static boolean hasAtLeastOneMethodOfMethodName(Class<?> clazz, String methodName) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (methodName == null) {
            throw new IllegalArgumentException("Method name must not be null");
        }
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method method : declaredMethods) {
            if (method.getName().equals(methodName)) {
                return true;
            }
        }
        Class<?>[] ifcs = clazz.getInterfaces();
        for (Class<?> ifc : ifcs) {
            if (hasAtLeastOneMethodOfMethodName(ifc, methodName)) {
                return true;
            }
        }
        return (clazz.getSuperclass() != null && hasAtLeastOneMethodOfMethodName(clazz.getSuperclass(), methodName));
    }
    
    /**
     * 获取类中声明一次的方法(包括父类)
     *
     * @param leafClass
     * @return
     * @throws IllegalArgumentException
     */
    public static Method[] getUniqueDeclaredMethods(Class<?> leafClass) throws IllegalArgumentException {
        final List<Method> methods = new ArrayList<Method>(32);
        doWithMethods(leafClass, new MethodCallback() {
            public void doWith(Method method) {
                boolean knownSignature = false;
                Method methodBeingOverriddenWithCovariantReturnType = null;

                for (Method existingMethod : methods) {
                    if (method.getName().equals(existingMethod.getName()) &&
                            Arrays.equals(method.getParameterTypes(), existingMethod.getParameterTypes())) {
                        // is this a covariant return type situation?
                        if (existingMethod.getReturnType() != method.getReturnType() &&
                                existingMethod.getReturnType().isAssignableFrom(method.getReturnType())) {
                            methodBeingOverriddenWithCovariantReturnType = existingMethod;
                        } else {
                            knownSignature = true;
                        }
                        break;
                    }
                }
                if (methodBeingOverriddenWithCovariantReturnType != null) {
                    methods.remove(methodBeingOverriddenWithCovariantReturnType);
                }
                if (!knownSignature && !isCglibRenamedMethod(method)) {
                    methods.add(method);
                }
            }
        });
        return methods.toArray(new Method[methods.size()]);
    }
    
    /**
     * 是否指定的类中可以复写指定的方法(即指定方法非私有的,且指定方法的类与指定的类在同一个包中)
     *
     * @param method 指定的方法
     * @param targetClass 指定的类
     * @return
     */
    private static boolean isOverridable(Method method, Class<?> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (Modifier.isPrivate(method.getModifiers())) {
            return false;
        }
        if (Modifier.isPublic(method.getModifiers()) || Modifier.isProtected(method.getModifiers())) {
            return true;
        }
        return getPackageName(method.getDeclaringClass()).equals(getPackageName(clazz));
    }
    
    /**
     * 获取最具体的方法
     *
     * @param method
     * @param targetClass
     * @return
     */
    public static Method getMostSpecificMethod(Method method, Class<?> clazz) {
        if (method != null && isOverridable(method, clazz) && clazz != null && !clazz.equals(method.getDeclaringClass())) {
            try {
                if (Modifier.isPublic(method.getModifiers())) {
                    try {
                        return clazz.getMethod(method.getName(), method.getParameterTypes());
                    }
                    catch (NoSuchMethodException ex) {
                        return method;
                    }
                }else {
                    Method specificMethod = findMethod(clazz, method.getName(), method.getParameterTypes());
                    return (specificMethod != null ? specificMethod : method);
                }
            }
            catch (AccessControlException ex) {
                // Security settings are disallowing reflective access; fall back to 'method' below.
            }
        }
        return method;
    }
    
    
    /**
     * 查找指定的公共方法(不包括父类)
     *
     * @param clazz
     * @param methodName
     * @param paramTypes
     * @return
     */
    public static Method findPublicMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (methodName == null) {
            throw new IllegalArgumentException("Method name must not be null");
        }
        try {
            return clazz.getMethod(methodName, paramTypes);
        }
        catch (NoSuchMethodException ex) {
            return null;
        }
    }
    
    /**
     *  查找指定的声明方法(不包括父类)
     *
     * @param clazz
     * @param methodName
     * @param paramTypes
     * @return
     */
    public static Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (methodName == null) {
            throw new IllegalArgumentException("Method name must not be null");
        }
        try {
            return clazz.getDeclaredMethod(methodName, paramTypes);
        }
        catch (NoSuchMethodException ex) {
            return null;
        }
    }
    
    /**
     *  查找指定的声明方法(不包括父类),并设置为可访问
     *
     * @param clazz
     * @param methodName
     * @param paramTypes
     * @return
     */
    public static Method findDeclaredMethodBySetAccessible(Class<?> clazz, String methodName, Class<?>... paramTypes) {
        Method method = findDeclaredMethod(clazz, methodName, paramTypes);
        if(method != null){
            makeAccessible(method);
        }
        return method;
    }

    /**
     * 查找类中的方法(包括父类)
     *
     * @param clazz
     * @param name
     * @param paramTypes
     * @return
     */
    public static Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (methodName == null) {
            throw new IllegalArgumentException("Method name must not be null");
        }
        Class<?> searchType = clazz;
        while (searchType != null) {
            Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods());
            for (Method method : methods) {
                if (methodName.equals(method.getName())
                        && (paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) {
                    return method;
                }
            }
            searchType = searchType.getSuperclass();
        }
        return null;
    }
    
    /**
     * 查找类中的方法(包括父类)
     *
     * @param clazz
     * @param name
     * @return
     */
    public static Method findMethod(Class<?> clazz, String methodName) {
        return findMethod(clazz, methodName, new Class[0]);
    }
    
    /**
     *  查找类中的方法(包括父类),并设置为可访问
     *
     * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object...args)
     *
     * @param target
     * @param methodName
     * @param parameterTypes
     * @return
     */
    public static Method findMethodBySetAccessible(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
        Method method = findMethod(clazz, methodName, parameterTypes);
        if(method != null){
            makeAccessible(method);
        }
        return method;
    }
    
    /**
     *  查找类中的方法(包括父类),并设置为可访问
     *
     * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object...args)
     *
     * @param target
     * @param methodName
     * @param parameterTypes
     * @return
     */
    public static Method findMethodBySetAccessible(Class<?> clazz, String methodName) {
        Method method = findMethod(clazz, methodName);
        if(method != null){
            makeAccessible(method);
        }
        return method;
    }
    
    /**
     *  查找对象中的方法(包括父类),并设置为可访问
     *
     * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object...args)
     *
     * @param target
     * @param methodName
     * @param parameterTypes
     * @return
     */
    public static Method findMethodBySetAccessible(Object target, String methodName, Class<?>... parameterTypes) {
        Method method = findMethod(target.getClass(), methodName, parameterTypes);
        if(method != null){
            makeAccessible(method);
        }
        return method;
    }
    
    /**
     *  查找对象中的方法(包括父类),并设置为可访问
     *
     * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object...args)
     *
     * @param target
     * @param methodName
     * @param parameterTypes
     * @return
     */
    public static Method findMethodBySetAccessible(Object target, String methodName) {
        Method method = findMethod(target.getClass(), methodName);
        if(method != null){
            makeAccessible(method);
        }
        return method;
    }
    
    /**
     * 调用指定对象的方法(不包括父类)
     *
     * @param method
     * @param target 指定对象
     * @param args 方法参数
     * @return
     */
    public static Object invokeMethod(Class<?> clazz, Method method, Object... args) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        if (method == null) {
            throw new IllegalArgumentException("Method must not be null");
        }
        try {        
            return method.invoke(getNewInstance(clazz), args);
        }
        catch (Exception ex) {
            handleReflectionException(ex);
        }
        throw new IllegalStateException("Should never get here");
    }
    
    /**
     * 调用指定对象的方法(不包括父类)
     *
     * @param method
     * @param target 指定对象
     * @param args 方法参数
     * @return
     */
    public static Object invokeMethod(Object target, Method method, Object... args) {
        try {
            return method.invoke(target, args);
        }
        catch (Exception ex) {
            handleReflectionException(ex);
        }
        throw new IllegalStateException("Should never get here");
    }
    
    /**
     * 调用指定对象的方法(不包括父类)
     *
     * @param method
     * @param target 指定对象
     * @return
     */
    public static Object invokeMethod(Class<?> clazz, Method method) {
        return invokeMethod(clazz, method, new Object[0]);
    }
    
    /**
     * 调用指定对象的方法(不包括父类)
     *
     * @param method
     * @param target 指定对象
     * @return
     */
    public static Object invokeMethod(Object target, Method method) {
        return invokeMethod(target, method, new Object[0]);
    }
    
    /**
     *
     * 调用指定对象的方法(无视不可访问),(不包括父类)
     *
     * 直接调用对象方法, 无视private/protected修饰符. 用于一次性调用的情况.
     * @param target 指定对象
     * @param methodName 方法名
     * @param parameterTypes 访问参数类型
     * @param args 参数
     * @return
     */
    public static Object invokeMethod(Class<?> clazz, String methodName, Class<?>[] parameterTypes, Object[] args) {
        if (methodName == null) {
            throw new IllegalArgumentException("Method must not be null");
        }
        Object target = getNewInstance(clazz);
        Method method = findDeclaredMethodBySetAccessible(target.getClass(), methodName, parameterTypes);
        if (method == null) {
            throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + target + "]");
        }

        try {
            return method.invoke(target, args);
        } catch (Exception e) {
            throw convertReflectionExceptionToUnchecked(e);
        }
    }
    
    /**
     *
     * 调用指定对象的方法(无视不可访问),(包括父类)
     *
     * 直接调用对象方法, 无视private/protected修饰符. 用于一次性调用的情况.
     * @param target 指定对象
     * @param methodName 方法名
     * @param parameterTypes 访问参数类型
     * @param args 参数
     * @return
     */
    public static Object invokeMethod(Object target, String methodName, Class<?>[] parameterTypes, Object[] args) {
        Method method = findDeclaredMethodBySetAccessible(target.getClass(), methodName, parameterTypes);
        if (method == null) {
            throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + target + "]");
        }

        try {
            return method.invoke(target, args);
        } catch (Exception e) {
            throw convertReflectionExceptionToUnchecked(e);
        }
    }
    
    /**
     *
     * 调用指定对象的方法(无视不可访问),(包括父类)
     *
     * 直接调用对象方法, 无视private/protected修饰符. 用于一次性调用的情况.
     * @param target 指定对象
     * @param methodName 方法名
     * @param parameterTypes 访问参数类型
     * @param args 参数
     * @return
     */
    public static Object invokeMethodIncludeParents(Class<?> clazz, String methodName, Class<?>[] parameterTypes, Object[] args) {
        if (methodName == null) {
            throw new IllegalArgumentException("Method must not be null");
        }
        Object target = getNewInstance(clazz);
        Method method = findMethodBySetAccessible(target, methodName, parameterTypes);
        if (method == null) {
            throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + target + "]");
        }

        try {
            return method.invoke(target, args);
        } catch (Exception e) {
            throw convertReflectionExceptionToUnchecked(e);
        }
    }
    
    /**
     *
     * 调用指定对象的方法(无视不可访问),(包括父类)
     *
     * 直接调用对象方法, 无视private/protected修饰符. 用于一次性调用的情况.
     * @param target 指定对象
     * @param methodName 方法名
     * @param parameterTypes 访问参数类型
     * @param args 参数
     * @return
     */
    public static Object invokeMethodIncludeParents(Object target, String methodName, Class<?>[] parameterTypes, Object[] args) {
        Method method = findMethodBySetAccessible(target, methodName, parameterTypes);
        if (method == null) {
            throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + target + "]");
        }

        try {
            return method.invoke(target, args);
        } catch (Exception e) {
            throw convertReflectionExceptionToUnchecked(e);
        }
    }
    
    /**
     * 调用Getter方法(无视不可访问)
     *
     * @param target 目标对象
     * @param propertyName 属性名
     * @return
     */
    public static Object invokeGetterMethod(Object target, String propertyName) {
        String getterMethodName = "get" + capitalize(propertyName);
        return invokeMethod(target, getterMethodName, new Class[] {}, new Object[] {});
    }
    
    /**
     * 调用Setter方法.使用value的Class来查找Setter方法
     *
     * @param target
     * @param propertyName 属性名
     * @param value
     */
    public static void invokeSetterMethod(Object target, String propertyName, Object value) {
        invokeSetterMethod(target, propertyName, value, null);
    }
    
    /**
     * 调用Setter方法(无视不可访问)
     *
     * @param target
     * @param propertyName 属性名
     * @param value
     * @param propertyType 用于查找Setter方法,为空时使用value的Class替代
     */
    public static void invokeSetterMethod(Object target, String propertyName, Object value, Class<?> propertyType) {
        Class<?> type = propertyType != null ? propertyType : value.getClass();
        String setterMethodName = "set" + capitalize(propertyName);
        invokeMethod(target, setterMethodName, new Class[] { type }, new Object[] { value });
    }
    
    /**
     * 调用指定对象的jdbc方法
     *
     * @param method
     * @param target
     * @param args
     * @return
     * @throws SQLException
     */
    public static Object invokeJdbcMethod(Method method, Object target, Object... args) throws SQLException {
        try {
            return method.invoke(target, args);
        }
        catch (IllegalAccessException ex) {
            handleReflectionException(ex);
        }
        catch (InvocationTargetException ex) {
            if (ex.getTargetException() instanceof SQLException) {
                throw (SQLException) ex.getTargetException();
            }
            handleInvocationTargetException(ex);
        }
        throw new IllegalStateException("Should never get here");
    }
    
    /**
     * 调用指定对象的jdbc方法
     *
     * @param method
     * @param target
     * @return
     * @throws SQLException
     */
    public static Object invokeJdbcMethod(Method method, Object target) throws SQLException {
        return invokeJdbcMethod(method, target, new Object[0]);
    }
    

    
    /**
     * 判断给定的方法是否是“equals”方法
     *
     * @param method
     * @return
     */
    public static boolean isEqualsMethod(Method method) {
        if (method == null || !method.getName().equals("equals")) {
            return false;
        }
        Class<?>[] paramTypes = method.getParameterTypes();
        return (paramTypes.length == 1 && paramTypes[0] == Object.class);
    }
    
    /**
     *  判断给定的方法是否是“hashCode”方法
     *
     * @param method
     * @return
     */
    public static boolean isHashCodeMethod(Method method) {
        return (method != null && method.getName().equals("hashCode") && method.getParameterTypes().length == 0);
    }
    
    /**
     * 判断给定的方法是否是“toString”方法
     *
     * @param method
     * @return
     */
    public static boolean isToStringMethod(Method method) {
        return (method != null && method.getName().equals("toString") && method.getParameterTypes().length == 0);
    }
    
    /**
     * 判断给定的方法是否是Object类拥有的方法
     *
     * @param method
     * @return
     */
    public static boolean isObjectMethod(Method method) {
        try {
            Object.class.getDeclaredMethod(method.getName(), method.getParameterTypes());
            return true;
        } catch (SecurityException ex) {
            return false;
        } catch (NoSuchMethodException ex) {
            return false;
        }
    }
    
    /**
     * 判断给定的方法是否是CGLIB重命名方法
     *
     * @param renamedMethod
     * @return
     */
    public static boolean isCglibRenamedMethod(Method renamedMethod) {
        return CGLIB_RENAMED_METHOD_PATTERN.matcher(renamedMethod.getName()).matches();
    }

    /**
     * 处理方法(回调方式,含过滤器)(包括父类)
     *
     * @param clazz 目标类
     * @param methodCallback 方法处理回调
     * @param methodFilter 方法过滤回调
     * @throws IllegalArgumentException
     */
    public static void doWithMethods(Class<?> clazz, MethodCallback methodCallback, MethodFilter methodFilter)
            throws IllegalArgumentException {

        // Keep backing up the inheritance hierarchy.
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (methodFilter != null && !methodFilter.matches(method)) {
                continue;
            }
            try {
                methodCallback.doWith(method);
            }
            catch (IllegalAccessException ex) {
                throw new IllegalStateException("Shouldn't be illegal to access method '" + method.getName()
                        + "': " + ex);
            }
        }
        if (clazz.getSuperclass() != null) {
            doWithMethods(clazz.getSuperclass(), methodCallback, methodFilter);
        }
        else if (clazz.isInterface()) {
            for (Class<?> superIfc : clazz.getInterfaces()) {
                doWithMethods(superIfc, methodCallback, methodFilter);
            }
        }
    }
    
    /**
     * 处理方法(回调方式,不含过滤器)(包括父类)
     *
     * @param clazz 目标类
     * @param methodCallback 方法处理回调
     * @throws IllegalArgumentException
     */
    public static void doWithMethods(Class<?> clazz, MethodCallback methodCallback) throws IllegalArgumentException {
        doWithMethods(clazz, methodCallback, null);
    }
    
    
    /**
     * 方法处理回调接口
     *
     * @author <a href="mailto:417877417@qq.com">menergy</a>
     * @version 2013-11-12
     */
    public interface MethodCallback {
        void doWith(Method method) throws IllegalArgumentException, IllegalAccessException;
    }
    
    /**
     * 方法过滤回调接口
     *
     * @author <a href="mailto:417877417@qq.com">menergy</a>
     * @version 2013-11-12
     */
    public interface MethodFilter {
        boolean matches(Method method);
    }
    
    /**
     * 匹配非桥接方法
     */
    public static MethodFilter NON_BRIDGED_METHODS = new MethodFilter() {

        public boolean matches(Method method) {
            return !method.isBridge();
        }
    };


    /**
     * 匹配非桥接且用户自定义的方法
     */
    public static MethodFilter USER_DECLARED_METHODS = new MethodFilter() {
        public boolean matches(Method method) {
            return (!method.isBridge() && method.getDeclaringClass() != Object.class);
        }
    };
    

    
/////////////////////////////////////////////////构造器反射///////////////////////////////////////////////////////
    
    

    /**
     * 设置构造器为可访问
     *
     * @param ctor
     */
    public static void makeAccessible(Constructor<?> ctor) {
        if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers()))
                && !ctor.isAccessible()) {
            ctor.setAccessible(true);
        }
    }
    
    /**
     * 是否有指定参数的公共构造器(不包括父类)
     *
     * @param clazz
     * @param paramTypes
     * @return
     */
    public static boolean hasPublicConstructor(Class<?> clazz, Class<?>... paramTypes) {
        return (findPublicConstructor(clazz, paramTypes) != null);
    }
    
    /**
     * 是否有指定参数的声明构造器(不包括父类)
     *
     * @param clazz
     * @param paramTypes
     * @return
     */
    public static boolean hasDeclaredConstructor(Class<?> clazz, Class<?>... paramTypes) {
        return (findDeclaredConstructor(clazz, paramTypes) != null);
    }
    
    /**
     * 查找指定参数的公共构造器(不包括父类)
     *
     * @param clazz
     * @param paramTypes
     * @return
     */
    public static Constructor<?> findPublicConstructor(Class<?> clazz, Class<?>... paramTypes) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        try {
            return clazz.getConstructor(paramTypes);
        }
        catch (NoSuchMethodException ex) {
            return null;
        }
    }
    
    /**
     * 获取指定参数的声明构造器(不包括父类)
     *
     * @param clazz
     * @param paramTypes
     * @return
     */
    public static Constructor<?> findDeclaredConstructor(Class<?> clazz, Class<?>... paramTypes){
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        try {
            return clazz.getDeclaredConstructor(paramTypes);
        }
        catch (NoSuchMethodException ex) {
            return null;
        }
    }
    
    /**
     * 获取类的所有指定参数的公共构造器(不包括父类)
     *
     * @param clazz
     * @return
     */
    public static Constructor<?>[] getAllPublicConstructor(Class<?> clazz){
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        return clazz.getConstructors();
    }
    
    /**
     * 获取所有指定参数的声明构造器(不包括父类)
     *
     * @param clazz
     * @return
     */
    public static Constructor<?>[] getAllDeclaredConstructor(Class<?> clazz){
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        return clazz.getDeclaredConstructors();
    }

    
    
/////////////////////////////////////////////////其它///////////////////////////////////////////////////////
    
    
    /**
     * 获得新对象
     *
     * @param clazz 类
     * @return
     */
    public static Object getNewInstance(Class<?> clazz){
        if (clazz == null) {
            throw new IllegalArgumentException("clazz must not be null");
        }
        Object obj = null;
        try {
            obj = clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if (obj == null) {
            throw new IllegalArgumentException("Error:the new object is null");
        }
        return obj;
    }
    
    /**
     * 获取包名,格式:"java.lang"
     *
     * @param clazz
     * @return
     */
    public static String getPackageName(Class<?> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class must not be null");
        }
        return getPackageName(clazz.getName());
    }
    
    /**
     * 获取包名,格式:"java.lang"
     *
     * @param fqClassName 全限定类名
     * @return
     */
    public static String getPackageName(String fqClassName) {
        if (fqClassName == null) {
            throw new IllegalArgumentException("Class name must not be null");
        }
        int lastDotIndex = fqClassName.lastIndexOf(".");
        return (lastDotIndex != -1 ? fqClassName.substring(0, lastDotIndex) : "");
    }


    /**
     * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class. eg. public UserDao
     * extends SimpleJPADao<User>
     *
     * @param clazz The class to introspect
     * @return the first generic declaration, or Object.class if cannot be
     *         determined
     */
    @SuppressWarnings( { "unchecked" })
    public static <T> Class<T> getSuperClassGenricType(final Class clazz) {
        return getSuperClassGenricType(clazz, 0);
    }

    /**
     * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
     *
     * 如public UserDao extends SimpleJPADao<User,Long>
     *
     * @param clazz clazz The class to introspect
     * @param index the Index of the generic ddeclaration,start from 0.
     * @return the index generic declaration, or Object.class if cannot be
     *         determined
     */
    @SuppressWarnings("unchecked")
    public static Class getSuperClassGenricType(final Class clazz, final int index) {

        Type genType = clazz.getGenericSuperclass();

        if (!(genType instanceof ParameterizedType)) {
            System.out.println(clazz.getSimpleName() + "'s superclass not ParameterizedType");
            return Object.class;
        }

        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

        if (index >= params.length || index < 0) {
            System.out.println("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length);
            return Object.class;
        }
        if (!(params[index] instanceof Class)) {
            System.out.println(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
            return Object.class;
        }

        return (Class) params[index];
    }

    
    /**
     * 将反射时的checked exception转换为unchecked exception.
     */
    public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {
        if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException || e instanceof NoSuchMethodException) {
            return new IllegalArgumentException("Reflection Exception.", e);
        } else if (e instanceof InvocationTargetException) {
            return new RuntimeException("Reflection Exception.", ((InvocationTargetException) e).getTargetException());
        } else if (e instanceof RuntimeException) {
            return (RuntimeException) e;
        }
        return new RuntimeException("Unexpected Checked Exception.", e);
    }
    
    /**
     * 处理反射异常
     *
     * @param ex
     */
    public static void handleReflectionException(Exception ex) {
        if (ex instanceof NoSuchMethodException) {
            throw new IllegalStateException("Method not found: " + ex.getMessage());
        }
        if (ex instanceof IllegalAccessException) {
            throw new IllegalStateException("Could not access method: " + ex.getMessage());
        }
        if (ex instanceof InvocationTargetException) {
            handleInvocationTargetException((InvocationTargetException) ex);
        }
        if (ex instanceof RuntimeException) {
            throw (RuntimeException) ex;
        }
        throw new UndeclaredThrowableException(ex);
    }
    
    /**
     *  处理调用目标异常
     *
     * @param ex
     */
    public static void handleInvocationTargetException(InvocationTargetException ex) {
        rethrowRuntimeException(ex.getTargetException());
    }
    
    /**
     * 重新抛出运行时异常或Error,即(不受检查异常)
     *
     * @param ex
     */
    public static void rethrowRuntimeException(Throwable ex) {
        if (ex instanceof RuntimeException) {
            throw (RuntimeException) ex;
        }
        if (ex instanceof Error) {
            throw (Error) ex;
        }
        throw new UndeclaredThrowableException(ex);
    }
    
    /**
     * 重新抛出异常
     *
     * @param ex
     * @throws Exception
     */
    public static void rethrowException(Throwable ex) throws Exception {
        if (ex instanceof Exception) {
            throw (Exception) ex;
        }
        if (ex instanceof Error) {
            throw (Error) ex;
        }
        throw new UndeclaredThrowableException(ex);
    }
    
    /**
     * 是否方法声明了该异常
     *
     * @param method
     * @param exceptionType
     * @return
     */
    public static boolean declaresException(Method method, Class<?> exceptionType) {
        if (method == null) {
            throw new IllegalArgumentException("Method must not be null");
        }
        Class<?>[] declaredExceptions = method.getExceptionTypes();
        for (Class<?> declaredException : declaredExceptions) {
            if (declaredException.isAssignableFrom(exceptionType)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 首字母大写
     *
     * @param str
     * @return
     */
    public static String capitalize(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return str;
        }
        return new StringBuffer(strLen)
            .append(Character.toTitleCase(str.charAt(0)))
            .append(str.substring(1))
            .toString();
    }
    

    /**
     *
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(ReflectionUtils.findField(ClassUtils.class, "CLASS_FILE_SUFFIX"));


    }

}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:64010次
    • 积分:1160
    • 等级:
    • 排名:千里之外
    • 原创:55篇
    • 转载:1篇
    • 译文:0篇
    • 评论:5条
    最新评论