Description
Returns object's method with the specified name and arguments.
License
Open Source License
Parameter
Parameter | Description |
---|
object | object |
methodName | method name |
arguments | method arguments |
Exception
Parameter | Description |
---|
NoSuchMethodException | an exception |
InvocationTargetException | an exception |
IllegalAccessException | an exception |
Return
object's method with the specified name and arguments
Declaration
public static Method getMethod(final Object object, final String methodName, final Object... arguments)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
Method Source Code
//package com.java2s;
/*/*from w ww. ja v a 2 s . c om*/
* This file is part of WebLookAndFeel library.
*
* WebLookAndFeel library 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.
*
* WebLookAndFeel library 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 WebLookAndFeel library. If not, see <http://www.gnu.org/licenses/>.
*/
import java.lang.reflect.*;
import java.util.*;
public class Main {
/**
* Methods lookup cache.
*/
private static final Map<Class, Map<String, Method>> methodsLookupCache = new HashMap<Class, Map<String, Method>>();
/**
* Returns object's method with the specified name and arguments.
* If method is not found in the object class all superclasses will be searched for that method.
*
* @param object object
* @param methodName method name
* @param arguments method arguments
* @return object's method with the specified name and arguments
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
public static Method getMethod(final Object object, final String methodName, final Object... arguments)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
return getMethod(object.getClass(), methodName, arguments);
}
/**
* Returns object's method with the specified name and arguments.
* If method is not found in the object class all superclasses will be searched for that method.
*
* @param aClass object class
* @param methodName method name
* @param arguments method arguments
* @return object's method with the specified name and arguments
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
public static Method getMethod(final Class aClass, final String methodName, final Object... arguments)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// todo Methods priority check (by super types)
// todo For now some method with [Object] arg might be used instead of method with [String]
// todo To avoid issues don't call methods with same amount of arguments and which are castable to each other
// Method key
final Class[] classTypes = getClassTypes(arguments);
final String key = aClass.getCanonicalName() + "." + methodName + argumentTypesToString(classTypes);
// Checking cache
Method method = null;
Map<String, Method> classMethodsCache = methodsLookupCache.get(aClass);
if (classMethodsCache != null) {
method = classMethodsCache.get(key);
} else {
classMethodsCache = new HashMap<String, Method>(1);
methodsLookupCache.put(aClass, classMethodsCache);
}
// Updating cache
if (method == null) {
method = getMethodImpl(aClass, methodName, arguments);
classMethodsCache.put(key, method);
}
return method;
}
/**
* Returns object's method with the specified name and arguments.
* If method is not found in the object class all superclasses will be searched for that method.
*
* @param topClass initial object class
* @param currentClass object class we are looking in for the method
* @param methodName method name
* @param types method argument types
* @return object's method with the specified name and arguments
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
private static Method getMethod(final Class topClass, final Class currentClass, final String methodName,
final Class[] types) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
// Searching for the specified method in object's class or one of its superclasses
for (final Method method : currentClass.getDeclaredMethods()) {
// Checking method name
if (method.getName().equals(methodName)) {
// Checking method arguments count
final Class<?>[] mt = method.getParameterTypes();
if (mt.length == types.length) {
// Checking that arguments fit
boolean fits = true;
for (int i = 0; i < mt.length; i++) {
if (!isAssignable(mt[i], types[i])) {
fits = false;
break;
}
}
if (fits) {
// Returning found method
return method;
}
}
}
}
// Search object superclass for this method
final Class superclass = currentClass.getSuperclass();
if (superclass != null) {
return getMethod(topClass, superclass, methodName, types);
}
// Throwing proper method not found exception
throw new NoSuchMethodException(
topClass.getCanonicalName() + "." + methodName + argumentTypesToString(types));
}
/**
* Returns class for the specified canonical name.
*
* @param canonicalName class canonical name
* @return class for the specified canonical name
* @throws ClassNotFoundException
*/
public static <T> Class<T> getClass(final String canonicalName) throws ClassNotFoundException {
return (Class<T>) Class.forName(canonicalName);
}
/**
* Returns an array of argument class types.
*
* @param arguments arguments to process
* @return an array of argument class types
*/
public static Class[] getClassTypes(final Object[] arguments) {
final Class[] parameterTypes = new Class[arguments.length];
for (int i = 0; i < arguments.length; i++) {
parameterTypes[i] = arguments[i] != null ? arguments[i].getClass() : null;
}
return parameterTypes;
}
/**
* Returns text representation for array of argument types.
*
* @param argTypes argument types
* @return text representation for array of argument types
*/
private static String argumentTypesToString(final Class[] argTypes) {
final StringBuilder buf = new StringBuilder("(");
if (argTypes != null) {
for (int i = 0; i < argTypes.length; i++) {
if (i > 0) {
buf.append(", ");
}
final Class c = argTypes[i];
buf.append((c == null) ? "null" : c.getCanonicalName());
}
}
return buf.append(")").toString();
}
/**
* Returns object's method with the specified name and arguments.
* If method is not found in the object class all superclasses will be searched for that method.
*
* @param aClass object class
* @param methodName method name
* @param arguments method arguments
* @return object's method with the specified name and arguments
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
protected static Method getMethodImpl(final Class aClass, final String methodName, final Object[] arguments)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
// This enhancement was a bad idea and was disabled
// In case method is protected/private or located in one of superclasses it won't be found
// if ( arguments.length == 0 )
// {
// // Searching simple method w/o arguments
// method = aClass.getMethod ( methodName );
// method.setAccessible ( true );
// }
// Searching for more complex method
final Class[] types = getClassTypes(arguments);
final Method method = getMethod(aClass, aClass, methodName, types);
method.setAccessible(true);
return method;
}
/**
* Returns whether first type is assignable from second one or not.
*
* @param type checked whether is assignable, always not null
* @param from checked type, might be null
* @return true if first type is assignable from second one, false otherwise
*/
public static boolean isAssignable(final Class type, final Class from) {
if (from == null) {
return !type.isPrimitive();
} else if (type.isAssignableFrom(from)) {
return true;
} else if (type.isPrimitive()) {
if (type == boolean.class) {
return Boolean.class.isAssignableFrom(from);
} else if (type == int.class) {
return Integer.class.isAssignableFrom(from);
} else if (type == char.class) {
return Character.class.isAssignableFrom(from);
} else if (type == byte.class) {
return Byte.class.isAssignableFrom(from);
} else if (type == short.class) {
return Short.class.isAssignableFrom(from);
} else if (type == long.class) {
return Long.class.isAssignableFrom(from);
} else if (type == float.class) {
return Float.class.isAssignableFrom(from);
} else if (type == double.class) {
return Double.class.isAssignableFrom(from);
} else if (type == void.class) {
return Void.class.isAssignableFrom(from);
}
}
return false;
}
}
Related
- getMethod(Class> klass, String methodName, Object... params)
- getMethod(Class> objectType, String methodName, Class>... parameterTypes)
- getMethod(Class> type, String name, Object[] args)
- getMethod(final Class extends Object> clazz, final String methodName, final Class>[] parTypes, final Object[] parameters)
- getMethod(final Object object, final String methodName, final Class>... parameterClass)
- getMethod(final Object object, final String methodName, final Object... arguments)
- getMethod(final Object object, String methodName, final Class>[] argTypes)
- getMethod(final Object target, final String methodName, final Class... argumentTypes)
- getMethod(final String methodName, final Object obj, final Class>... argTypes)