Here you can find the source of invokeMethod(Object target, String name, Object[] args, Class[] argTypes)
public static Object invokeMethod(Object target, String name, Object[] args, Class[] argTypes) throws Throwable
//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; } }