Java Reflection Method Invoke invokeMethod(Object target, String name, Object[] args, Class[] argTypes)

Here you can find the source of invokeMethod(Object target, String name, Object[] args, Class[] argTypes)

Description

invoke Method

License

Open Source License

Declaration

public static Object invokeMethod(Object target, String name,
            Object[] args, Class[] argTypes) throws Throwable 

Method Source Code

//package com.java2s;
/*//from w w  w  .java2 s. c  o m

 Copyright (C) 2007-2016 Michael Goffioul

 This file is part of Octave.

 Octave is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version.

 Octave is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Octave; see the file COPYING.  If not, see
 <http://www.gnu.org/licenses/>.

 */

import java.lang.reflect.*;

public class Main {
    private static Object invokeMethod(Method m, Object target,
            Object[] args) throws Exception {
        try {
            return m.invoke(target, args);
        } catch (IllegalAccessException ex) {
            String mName = m.getName();
            Class[] pTypes = m.getParameterTypes();
            Class currClass = target.getClass();

            while (currClass != null) {
                try {
                    Method meth = currClass.getMethod(mName, pTypes);
                    if (!meth.equals(m)) {
                        return meth.invoke(target, args);
                    }
                } catch (NoSuchMethodException ex2) {
                } catch (IllegalAccessException ex2) {
                }

                Class[] ifaceList = currClass.getInterfaces();
                for (int i = 0; i < ifaceList.length; i++) {
                    try {
                        Method meth = ifaceList[i].getMethod(mName, pTypes);
                        return meth.invoke(target, args);
                    } catch (NoSuchMethodException ex2) {
                    } catch (IllegalAccessException ex2) {
                    }
                }

                currClass = currClass.getSuperclass();
            }

            throw ex;
        }
    }

    public static Object invokeMethod(Object target, String name,
            Object[] args, Class[] argTypes) throws Throwable {
        Method m = findMethod(target.getClass(), name, argTypes);
        if (m != null) {
            try {
                Object result = invokeMethod(
                        m,
                        target,
                        castArguments(args, argTypes, m.getParameterTypes()));
                return result;
            } catch (InvocationTargetException ex) {
                throw ex.getCause();
            }
        } else {
            throw new NoSuchMethodException(name);
        }
    }

    public static Method findMethod(Class cls, String name, Class[] argTypes) {
        try {
            return cls.getMethod(name, argTypes);
        } catch (Exception e) {
            Method[] mList = cls.getMethods();
            Method m;
            for (int i = 0; i < mList.length; i++) {
                m = mList[i];
                if (m.getName().equals(name)
                        && m.getParameterTypes().length == argTypes.length
                        && isCallableFrom(m, argTypes)) {
                    return m;
                }
            }
            return null;
        }
    }

    private static Object[] castArguments(Object[] args, Class[] argTypes,
            Class[] expTypes) {
        for (int i = 0; i < args.length; i++) {
            args[i] = castArgument(args[i], argTypes[i], expTypes[i]);
        }
        return args;
    }

    public static String getMethods(String classname)
            throws ClassNotFoundException {
        return (getMethods(Class.forName(classname)));
    }

    public static String getMethods(Object obj)
            throws ClassNotFoundException {
        return (getMethods(obj.getClass()));
    }

    public static String getMethods(Class klass) {
        StringBuffer sb = new StringBuffer();

        Method theMethod[] = klass.getMethods();
        for (int i = 0; i < theMethod.length; i++) {
            if (i > 0) {
                sb.append(";");
            }
            sb.append(theMethod[i].getReturnType().getCanonicalName());
            sb.append(" ");
            sb.append(theMethod[i].getName());
            sb.append("(");

            Class theParameter[] = theMethod[i].getParameterTypes();
            for (int j = 0; j < theParameter.length; j++) {
                if (j > 0) {
                    sb.append(", ");
                }
                sb.append(theParameter[j].getCanonicalName());
            }
            sb.append(")");

            Class theExceptions[] = theMethod[i].getExceptionTypes();
            if (theExceptions.length > 0) {
                sb.append(" throws ");
                for (int j = 0; j < theExceptions.length; j++) {
                    if (j > 0) {
                        sb.append(", ");
                    }
                    sb.append(theExceptions[j].getCanonicalName());
                }
            }
        }

        return (sb.toString());
    }

    private static boolean isCallableFrom(Method m, Class[] argTypes) {
        Class[] expTypes = m.getParameterTypes();
        for (int i = 0; i < argTypes.length; i++) {
            if (!isCallableFrom(expTypes[i], argTypes[i])) {
                return false;
            }
        }
        return true;
    }

    private static boolean isCallableFrom(Constructor c, Class[] argTypes) {
        Class[] expTypes = c.getParameterTypes();
        for (int i = 0; i < argTypes.length; i++) {
            if (!isCallableFrom(expTypes[i], argTypes[i])) {
                return false;
            }
        }
        return true;
    }

    private static boolean isCallableFrom(Class expCls, Class argCls) {
        //System.out.println("isCallableFrom: "+expCls.getCanonicalName() + " <=? " + argCls.getCanonicalName());
        if (argCls == null) {
            return !expCls.isPrimitive();
        } else if (expCls.isAssignableFrom(argCls)) {
            return true;
        } else if ((isNumberClass(expCls) || isBooleanClass(expCls))
                && isNumberClass(argCls)) {
            return true;
        } else if (isCharClass(expCls) && argCls.equals(Character.class)) {
            /*
              modified into a more strict check to avoid char to string matching
              to avoid matching method signatureslike
              java_method(char) with octave_call('a String')
              Date: 28-08-2010
              Author: Martin Hepperle
             */
            return true;
        } else if (isStringClass(expCls) && argCls.equals(String.class)) {
            /*
              added for strict String to String matching
              java_method(String) with octave_call('a String')
              but not
              java_method(char) with octave_call('a String')
              Date: 28-08-2010
              Author: Martin Hepperle
             */
            return true;
        } else if (expCls.isArray()
                && argCls.isArray()
                && isCallableFrom(expCls.getComponentType(),
                        argCls.getComponentType())) {
            return true;
        } else if (expCls.equals(Object.class) && argCls.isPrimitive()) {
            return true;
        } else {
            return false;
        }
    }

    private static Object castArgument(Object obj, Class type, Class expType) {
        // System.out.println("expType:"+expType.getCanonicalName() + " <= type:" + type.getCanonicalName());
        if (type == null || expType.isAssignableFrom(type)) {
            return obj;
        } else if (isNumberClass(expType)) {
            if (expType.equals(Integer.TYPE)
                    || expType.equals(Integer.class)) {
                return new Integer(((Number) obj).intValue());
            } else if (expType.equals(Double.TYPE)
                    || expType.equals(Double.class)) {
                return new Double(((Number) obj).doubleValue());
            } else if (expType.equals(Short.TYPE)
                    || expType.equals(Short.class)) {
                return new Short(((Number) obj).shortValue());
            } else if (expType.equals(Long.TYPE)
                    || expType.equals(Long.class)) {
                return new Long(((Number) obj).longValue());
            } else if (expType.equals(Float.TYPE)
                    || expType.equals(Float.class)) {
                return new Float(((Number) obj).floatValue());
            }
        } else if (isBooleanClass(expType)) {
            return new Boolean(((Number) obj).intValue() != 0);
        } else if (isCharClass(expType)) {
            String s = obj.toString();
            if (s.length() != 1) {
                throw new ClassCastException("cannot cast " + s
                        + " to character");
            }
            return new Character(s.charAt(0));
        } else if (expType.isArray() && type.isArray()) {
            return castArray(obj, type.getComponentType(),
                    expType.getComponentType());
        } else if (type.isPrimitive()) {
            return obj;
        }
        return null;
    }

    private static boolean isNumberClass(Class cls) {
        return (cls.equals(Integer.TYPE) || cls.equals(Integer.class)
                || cls.equals(Short.TYPE) || cls.equals(Short.class)
                || cls.equals(Long.TYPE) || cls.equals(Long.class)
                || cls.equals(Float.TYPE) || cls.equals(Float.class)
                || cls.equals(Double.TYPE) || cls.equals(Double.class));
    }

    private static boolean isBooleanClass(Class cls) {
        return (cls.equals(Boolean.class) || cls.equals(Boolean.TYPE));
    }

    private static boolean isCharClass(Class cls) {
        return (cls.equals(Character.class) || cls.equals(Character.TYPE));
    }

    /**
     * Check whether the supplied class is a String class.
     *
     * Added for more strict char/string mathicng of method signatures
     * Date: 28-08-2010
     * Author: Martin Hepperle
     * @param cls Class - the class to check
     * @return boolean - true if clas is of class java.lang.String
     */
    private static boolean isStringClass(Class cls) {
        return (cls.equals(String.class));
    }

    private static Object castArray(Object obj, Class elemType,
            Class elemExpType) {
        int len = Array.getLength(obj);
        Object result = Array.newInstance(elemExpType, len);
        for (int i = 0; i < len; i++) {
            Array.set(result, i,
                    castArgument(Array.get(obj, i), elemType, elemExpType));
        }
        return result;
    }
}

Related

  1. invokeMethod(Object target, Method method, Object[] args)
  2. invokeMethod(Object target, String method)
  3. invokeMethod(Object target, String methodName, Object... parameters)
  4. invokeMethod(Object target, String methodName, Object[] arguments)
  5. invokeMethod(Object target, String name, Class... parameterTypes)
  6. invokeMethod(Object target, String signature, Object... args)
  7. invokeMethod(Object target, String thisMethod, Object value)
  8. invokeMethod(Object theObject, String methodName, Object... parametersObject)
  9. invokeMethod(String className, String method, Class[] paramTypes, Object obj, Object[] args)