Java Reflection Method Invoke invokeMethod(Object object, String methodName, List argList)

Here you can find the source of invokeMethod(Object object, String methodName, List argList)

Description

invoke Method

License

Apache License

Declaration

public static Object invokeMethod(Object object, String methodName, List<?> argList)
            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException 

Method Source Code


//package com.java2s;
/*/*  w  w  w . j a v a  2s .  co m*/
 * Copyright (c) 2010-2013 Evolveum
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

public class Main {
    public static Object invokeMethod(Object object, String methodName, List<?> argList)
            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        Method method = findMethod(object, methodName, argList);
        if (method == null) {
            throw new NoSuchMethodException(
                    "No method " + methodName + " for arguments " + debugDumpArgList(argList) + " in " + object);
        }
        Object[] args = argList.toArray();
        if (method.isVarArgs()) {
            Class<?> parameterTypeClass = method.getParameterTypes()[0];
            Object[] varArgs = (Object[]) Array.newInstance(parameterTypeClass.getComponentType(), args.length);
            for (int i = 0; i < args.length; i++) {
                varArgs[i] = args[i];
            }
            args = new Object[] { varArgs };
        }
        try {
            return method.invoke(object, args);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException(
                    e.getMessage() + " for arguments " + debugDumpArgList(argList) + " in " + object, e);
        }
    }

    public static Method findMethod(Object object, String methodName, int arity) {
        for (Method method : object.getClass().getMethods()) {
            if (method.getName().equals(methodName) && method.getParameterTypes().length == arity
                    && !method.isVarArgs()) {
                return method;
            }
        }
        return null;
    }

    public static Method findMethod(Object object, String methodName, List<?> argList) throws SecurityException {
        Method method = findMethodDirect(object, methodName, argList);
        if (method != null) {
            return method;
        }
        method = findMethodCompatible(object, methodName, argList);
        if (method != null) {
            return method;
        }
        // We cannot find method directly. Try varargs.
        method = findVarArgsMethod(object, methodName);
        return method;
    }

    public static String debugDumpArgList(List<?> argList) {
        StringBuilder sb = new StringBuilder();
        boolean sep = false;
        for (Object arg : argList) {
            if (sep) {
                sb.append(", ");
            } else {
                sep = true;
            }
            if (arg == null) {
                sb.append("null");
            } else {
                sb.append(arg.getClass().getName());
                sb.append(":");
                sb.append(arg);
            }
        }
        return sb.toString();
    }

    private static Method findMethodDirect(Object object, String methodName, List<?> argList)
            throws SecurityException {
        Class<?>[] parameterTypes = new Class[argList.size()];
        for (int i = 0; i < argList.size(); i++) {
            parameterTypes[i] = argList.get(i).getClass();
        }
        try {
            return object.getClass().getMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException e) {
            return null;
        }
    }

    /**
     * Rough lookup of a compatible method. It takes first method with matching name, number of parameters and compatible
     *  parameter values. It is not perfect, e.g. it cannot select foo(String) instead of foo(Object). But it is better than
     *  nothing. And stock Java reflection has really nothing.
     */
    private static Method findMethodCompatible(Object object, String methodName, List<?> argList)
            throws SecurityException {
        for (Method method : object.getClass().getMethods()) {
            if (method.getName().equals(methodName)) {
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (parameterTypes.length == argList.size()) {
                    boolean wrong = false;
                    for (int i = 0; i < parameterTypes.length; i++) {
                        Object arg = argList.get(i);
                        if (arg == null) {
                            // null argument matches any parameter type
                        } else {
                            if (!parameterTypes[i].isAssignableFrom(arg.getClass())) {
                                wrong = true;
                                break;
                            }
                        }
                    }
                    if (!wrong) {
                        // We got it. We have compatible signature here.
                        return method;
                    }
                }
            }
        }
        return null;
    }

    public static Method findVarArgsMethod(Object object, String methodName) {
        for (Method method : object.getClass().getMethods()) {
            if (method.getName().equals(methodName) && method.isVarArgs()) {
                return method;
            }
        }
        return null;
    }
}

Related

  1. invokeMethod(Object obj, String methodName, Object... params)
  2. invokeMethod(Object obj, String methodName, Object[] params, Class[] paramTypes)
  3. invokeMethod(Object object, Method method, Object... args)
  4. invokeMethod(Object object, String methodName, Class[] parameterTypes, Object[] parameters)
  5. invokeMethod(Object object, String methodName, Class[] signature, Object[] parameters)
  6. invokeMethod(Object object, String methodName, Object arg, Class argType)
  7. invokeMethod(Object object, String methodName, Object... parameters)
  8. invokeMethod(Object object, String methodName, Object[] args, Class[] parameterTypes)
  9. invokeMethod(Object object, String methodName, Object[] params, Object[] result)