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

com.yixan.tools.common.util.ReflectUtil Maven / Gradle / Ivy

There is a newer version: 3.7.1
Show newest version
package com.yixan.tools.common.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 反射工具类
 *
 * @author zhaohuihua
 * @version V1.0 2017年5月26日
 */
public abstract class ReflectUtil {

    public static String getMethodLogSignature(Class clazz, String method, Class... types) {
        StringBuilder buffer = new StringBuilder();
        buffer.append(clazz.getSimpleName());
        buffer.append(".");
        buffer.append(method);
        buffer.append("(");
        for (int i = 0; i < types.length; i++) {
            if (i > 0) {
                buffer.append(',');
            }
            buffer.append(types[i].getSimpleName());
        }
        buffer.append(")");
        return buffer.toString();
    }

    public static Method findMethod(Class clazz, String name, Class... types) throws NoSuchMethodException {

        try {
            return clazz.getMethod(name, types);
        } catch (NoSuchMethodException e) {
            return eachFindMethod(clazz, name, types);
        }
    }

    /**
     * 优先选择参数类型完全相同的, 其次选择通过装箱/拆箱能匹配的或父子关系能匹配的
* 总之:
* 如果有一个方法xxxMethod(List<?> list, Integer i)
* 通过eachFindMethod(clazz, "xxxMethod", List.class, Integer.class);能找到
* 通过eachFindMethod(clazz, "xxxMethod", List.class, int.class);能找到
* 通过eachFindMethod(clazz, "xxxMethod", ArrayList.class, Integer.class);能找到
* 通过eachFindMethod(clazz, "xxxMethod", ArrayList.class, int.class);也能找到
* * @param clazz 类 * @param name 方法名 * @param types 参数列表 * @return 方法对象 * @throws NoSuchMethodException */ private static Method eachFindMethod(Class clazz, String name, Class... types) throws NoSuchMethodException { // 直接采用clazz.getMethod(name, types)的方式 // 会出现根据int找不到clazz.method(Integer), 根据Integer找不到clazz.method(Object)的情况 List accepted = new ArrayList<>(); // 可接受的(通过装箱/拆箱能匹配的或父子关系能匹配的) int length = types.length; Method[] methods = clazz.getMethods(); for (Method m : methods) { if (!name.equals(m.getName())) { continue; // 方法名不符 } Class[] actuals = m.getParameterTypes(); if (actuals.length != types.length) { continue; // 参数个数不符 } boolean equals = true; boolean accept = true; for (int i = 0; i < length; i++) { Class a = actuals[i]; Class t = types[i]; if (a != t) { equals = false; } if (a != t && !a.isAssignableFrom(t) && !isCompatible(a, t)) { accept = false; } } if (equals) { return m; // 参数类型完全相同, 直接返回 } if (accept) { accepted.add(m); } } if (!accepted.isEmpty()) { // 没有参数类型完全相同, 但有通过装箱/拆箱能匹配的或父子关系能匹配的 if (accepted.size() == 1) { // 如果只有一个这种方法, 就选择这个啦 return accepted.get(0); } else { // 如果不只一个, 那没办法, 报个错吧 String signature = getMethodLogSignature(clazz, name, types); throw new NoSuchMethodException("The method " + signature + " is ambiguous."); } } else { String signature = getMethodLogSignature(clazz, name, types); throw new NoSuchMethodException("The method " + signature + " not found."); } } private static boolean isCompatible(Class a, Class b) { if (a == b) { return true; } else if (a == boolean.class && b == Boolean.class || b == boolean.class && a == Boolean.class) { return true; } else if (a == char.class && b == Character.class || b == char.class && a == Character.class) { return true; } else if (a == byte.class && b == Byte.class || b == byte.class && a == Byte.class) { return true; } else if (a == short.class && b == Short.class || b == short.class && a == Short.class) { return true; } else if (a == int.class && b == Integer.class || b == int.class && a == Integer.class) { return true; } else if (a == long.class && b == Long.class || b == long.class && a == Long.class) { return true; } else if (a == float.class && b == Float.class || b == float.class && a == Float.class) { return true; } else if (a == double.class && b == Double.class || b == double.class && a == Double.class) { return true; } return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy