Description
Invoke the named method in the given object or its superclasses.
License
Open Source License
Parameter
Parameter | Description |
---|
obj | The object. |
methodName | The method name. |
throwException | If true, throw an exception if the field value could not be read. |
Exception
Parameter | Description |
---|
IllegalArgumentException | If the field value could not be read. |
Return
The field value.
Declaration
public static Object invokeMethod(final Object obj, final String methodName, final boolean throwException)
throws IllegalArgumentException
Method Source Code
//package com.java2s;
/*/*w ww . j av a2 s .c o m*/
* This file is part of ClassGraph.
*
* Author: Luke Hutchison
*
* Hosted at: https://github.com/lukehutch/fast-classpath-scanner
*
* --
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Luke Hutchison
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
* EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
* OR OTHER DEALINGS IN THE SOFTWARE.
*/
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class Main {
/**
* Invoke the named method in the given object or its superclasses. If an exception is thrown while trying to
* call the method, and throwException is true, then IllegalArgumentException is thrown wrapping the cause,
* otherwise this will return null. If passed a null object, returns null unless throwException is true, then
* throws IllegalArgumentException.
*
* @param obj
* The object.
* @param methodName
* The method name.
* @param throwException
* If true, throw an exception if the field value could not be read.
* @return The field value.
* @throws IllegalArgumentException
* If the field value could not be read.
*/
public static Object invokeMethod(final Object obj, final String methodName, final boolean throwException)
throws IllegalArgumentException {
if (obj != null) {
final Class<? extends Object> cls = obj.getClass();
// Iterate through implemented interfaces, top-down, then superclass to subclasses, top-down
// (since higher-up superclasses and superinterfaces have the highest chance of being visible)
final List<Class<?>> reverseAttemptOrder = getReverseMethodAttemptOrder(cls);
IllegalAccessException illegalAccessException = null;
for (int i = reverseAttemptOrder.size() - 1; i >= 0; i--) {
final Class<?> iface = reverseAttemptOrder.get(i);
try {
// Try calling method on interface
final Method method = iface.getDeclaredMethod(methodName);
try {
method.setAccessible(true);
} catch (final Exception e) {
}
return method.invoke(obj);
} catch (final NoSuchMethodException e) {
// Fall through if method not found, since a superinterface might have the method
} catch (final IllegalAccessException e) {
illegalAccessException = e;
} catch (final Throwable e) {
if (throwException) {
throw new IllegalArgumentException("Exception while invoking method \"" + methodName + "\"",
e);
}
}
}
if (throwException) {
if (illegalAccessException != null) {
throw new IllegalArgumentException("Method \"" + methodName + "\" is not accessible",
illegalAccessException);
} else {
throw new IllegalArgumentException("Method \"" + methodName + "\" doesn't exist");
}
}
} else if (throwException) {
throw new IllegalArgumentException("Can't invoke method on null object");
}
return null;
}
/**
* Invoke the named method in the given object or its superclasses. If an exception is thrown while trying to
* call the method, and throwException is true, then IllegalArgumentException is thrown wrapping the cause,
* otherwise this will return null. If passed a null object, returns null unless throwException is true, then
* throws IllegalArgumentException.
*
* @param obj
* The object.
* @param methodName
* The method name.
* @param argType
* The type of the parameter.
* @param arg
* The argument value.
* @param throwException
* Whether to throw an exception on failure.
* @return The result of the method invocation.
* @throws IllegalArgumentException
* If the method could not be invoked.
*/
public static Object invokeMethod(final Object obj, final String methodName, final Class<?> argType,
final Object arg, final boolean throwException) throws IllegalArgumentException {
if (obj != null) {
final Class<? extends Object> cls = obj.getClass();
// Iterate through implemented interfaces, top-down, then superclass to subclasses, top-down
// (since higher-up superclasses and superinterfaces have the highest chance of being visible)
final List<Class<?>> reverseAttemptOrder = getReverseMethodAttemptOrder(cls);
IllegalAccessException illegalAccessException = null;
for (int i = reverseAttemptOrder.size() - 1; i >= 0; i--) {
final Class<?> iface = reverseAttemptOrder.get(i);
try {
// Try calling method on interface
final Method method = iface.getDeclaredMethod(methodName, argType);
try {
method.setAccessible(true);
} catch (final Exception e) {
}
return method.invoke(obj, arg);
} catch (final NoSuchMethodException e) {
// Fall through if method not found, since a superinterface might have the method
} catch (final IllegalAccessException e) {
illegalAccessException = e;
} catch (final Throwable e) {
if (throwException) {
throw new IllegalArgumentException("Exception while invoking method \"" + methodName + "\"",
e);
}
}
}
if (throwException) {
if (illegalAccessException != null) {
throw new IllegalArgumentException("Method \"" + methodName + "\" is not accessible",
illegalAccessException);
} else {
throw new IllegalArgumentException("Method \"" + methodName + "\" doesn't exist");
}
}
} else if (throwException) {
throw new IllegalArgumentException("Can't invoke method on null object");
}
return null;
}
/**
* Iterate through implemented interfaces, top-down, then superclass to subclasses, top-down (since higher-up
* superclasses and superinterfaces have the highest chance of being visible).
*/
private static List<Class<?>> getReverseMethodAttemptOrder(final Class<?> cls) {
final List<Class<?>> reverseAttemptOrder = new ArrayList<>();
// Iterate from class to its superclasses
for (Class<?> c = cls; c != null && c != Object.class; c = c.getSuperclass()) {
reverseAttemptOrder.add(c);
}
// Find interfaces and superinterfaces implemented by this class or its superclasses
final Set<Class<?>> addedIfaces = new HashSet<>();
final LinkedList<Class<?>> ifaceQueue = new LinkedList<>();
for (Class<?> c = cls; c != null; c = c.getSuperclass()) {
if (c.isInterface()) {
if (addedIfaces.add(c)) {
ifaceQueue.add(c);
}
}
for (final Class<?> iface : c.getInterfaces()) {
if (addedIfaces.add(iface)) {
ifaceQueue.add(iface);
}
}
}
while (!ifaceQueue.isEmpty()) {
final Class<?> iface = ifaceQueue.remove();
reverseAttemptOrder.add(iface);
final Class<?>[] superIfaces = iface.getInterfaces();
if (superIfaces.length > 0) {
for (final Class<?> superIface : superIfaces) {
if (addedIfaces.add(superIface)) {
ifaceQueue.add(superIface);
}
}
}
}
return reverseAttemptOrder;
}
}
Related
- invokeMethod(final Method method, final Object instance, final Object... args)
- invokeMethod(final Method method, final Object object)
- invokeMethod(final Method method, final Object object, final Object[] args)
- invokeMethod(final Object instance, final String methodName, final Class>[] parTypes, final Object[] parameters)
- invokeMethod(final Object obj, final Method method, final Object... args)
- invokeMethod(final Object object, final String methodName, final Class>[] parameterTypes, final Object[] parameters)
- invokeMethod(final Object object, final String methodName, final Class>[] paramTypes, final Object[] parameters)
- invokeMethod(final Object p, final String methodName)
- invokeMethod(java.lang.Object toObj, String tcMethodName, Class toResultClass)