package info.gy.zlzj.rs.salary.service;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class ReflectInvokeUtil {
public static void invokeMethod(String methodFullName, Map<String, Object> params)
throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
if (!isValidMethodFullName(methodFullName)) return;
Class<?> objectClass = Class.forName(getClassName(methodFullName)); //目标类Class对象
String objectMethodName = getMethodName(methodFullName); //目标方法名称
List<Method> objectMethods = filterObjectMethod(objectClass.getMethods(), objectMethodName, params);
List<Object[]> objectMethodParamValues = getMethodParamValues(objectMethods, params);
int index = 0;
for (Method objectMethod : objectMethods) {
objectMethod.invoke(objectClass.newInstance(), objectMethodParamValues.get(index));
index++;
}
}
private static boolean isValidMethodFullName(String methodFullName) {
if (methodFullName == null) throw new NullPointerException("method full name can`t null!");
return methodFullName.contains(".");
}
private static String getClassName(String methodFullName) {
return methodFullName.substring(0, methodFullName.lastIndexOf("."));
}
private static String getMethodName(String methodFullName) {
return methodFullName.substring(methodFullName.lastIndexOf(".") + 1);
}
private static List<Method> filterObjectMethod(Method[] methods, String objectMethodName, Map<String, Object> params) {
return Arrays.stream(methods).filter(method -> {
boolean isNameEquals = method.getName().equals(objectMethodName);
boolean isParamLengthEquals = method.getParameters().length == params.size();
if (isNameEquals && isParamLengthEquals) {
String[] parameterNames = getMethodParamNames(method);
if (parameterNames != null) {
return isParamNameEquals(parameterNames, params) && isParamClassEquals(method, params);
} else {
return isParamClassEquals(method, params);
}
}
return false;
}).collect(Collectors.toList());
}
private static List<Object[]> getMethodParamValues(List<Method> objectMethods, Map<String, Object> params) {
List<Object[]> paramValueList = new ArrayList<>();
objectMethods.forEach(method -> {
String[] methodParamNames = getMethodParamNames(method);
if (methodParamNames != null) {
Object[] paramValues = new Object[methodParamNames.length];
AtomicInteger index = new AtomicInteger();
Arrays.stream(methodParamNames).forEach(paramName -> {
paramValues[index.getAndIncrement()] = params.get(paramName);
});
paramValueList.add(paramValues);
}
});
return paramValueList;
}
private static String[] getMethodParamNames(Method method) {
Parameter[] parameters = method.getParameters();
String[] paramNames = new String[parameters.length];
for (int i = 0; i < paramNames.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isNamePresent()) return null;
paramNames[i] = parameter.getName();
}
return paramNames;
}
private static boolean isParamNameEquals(String[] parameterNames, Map<String, Object> params) {
if (parameterNames.length != params.size()) return false;
for (String paramName : parameterNames) {
if (!params.containsKey(paramName)) {
return false;
}
}
return true;
}
private static boolean isParamClassEquals(Method method, Map<String, Object> params) {
boolean isEquals = Arrays.equals(getMethodParamValueClass(method), getMethodParamValueClass(params));
return isEquals;
}
private static Class<?>[] getMethodParamValueClass(Method method) {
Parameter[] parameters = method.getParameters();
Class<?>[] paramValueClasses = new Class[parameters.length];
int index = 0;
for (Parameter parameter : parameters) {
paramValueClasses[index] = basicClassConvert(parameter.getType());
index++;
}
return paramValueClasses;
}
private static Class<?>[] getMethodParamValueClass(Map<String, Object> params) {
Class<?>[] paramValueClasses = new Class[params.size()];
AtomicInteger index = new AtomicInteger(0);
params.forEach((k, v) -> paramValueClasses[index.getAndIncrement()] = v.getClass());
return paramValueClasses;
}
private static Class<?> basicClassConvert(Class<?> basicClass) {
if (byte.class.equals(basicClass)) {
return byte.class;
}
if (short.class.equals(basicClass)) {
return Short.class;
}
if (int.class.equals(basicClass)) {
return Integer.class;
}
if (long.class.equals(basicClass)) {
return Long.class;
}
if (char.class.equals(basicClass)) {
return Character.class;
}
if (boolean.class.equals(basicClass)) {
return Boolean.class;
}
if (float.class.equals(basicClass)) {
return Float.class;
}
if (double.class.equals(basicClass)) {
return Double.class;
}
return basicClass;
}
}
Java的反射调用
最新推荐文章于 2023-12-07 11:55:27 发布