📄 methodutils.java
字号:
Object[] args = {arg}; return invokeExactMethod(object, methodName, args); } /** * <p>Invoke a method whose parameter types match exactly the object * types.</p> * * <p> This uses reflection to invoke the method obtained from a call to * {@link #getAccessibleMethod}.</p> * * @param object invoke method on this object * @param methodName get method with this name * @param args use these arguments - treat null as empty array * * @throws NoSuchMethodException if there is no such accessible method * @throws InvocationTargetException wraps an exception thrown by the * method invoked * @throws IllegalAccessException if the requested method is not accessible * via reflection */ public static Object invokeExactMethod( Object object, String methodName, Object[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (args == null) { args = emptyObjectArray; } int arguments = args.length; Class parameterTypes [] = new Class[arguments]; for (int i = 0; i < arguments; i++) { parameterTypes[i] = args[i].getClass(); } return invokeExactMethod(object, methodName, args, parameterTypes); } /** * <p>Invoke a method whose parameter types match exactly the parameter * types given.</p> * * <p>This uses reflection to invoke the method obtained from a call to * {@link #getAccessibleMethod}.</p> * * @param object invoke method on this object * @param methodName get method with this name * @param args use these arguments - treat null as empty array * @param parameterTypes match these parameters - treat null as empty array * * @throws NoSuchMethodException if there is no such accessible method * @throws InvocationTargetException wraps an exception thrown by the * method invoked * @throws IllegalAccessException if the requested method is not accessible * via reflection */ public static Object invokeExactMethod( Object object, String methodName, Object[] args, Class[] parameterTypes) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (args == null) { args = emptyObjectArray; } if (parameterTypes == null) { parameterTypes = emptyClassArray; } Method method = getAccessibleMethod( object.getClass(), methodName, parameterTypes); if (method == null) throw new NoSuchMethodException("No such accessible method: " + methodName + "() on object: " + object.getClass().getName()); return method.invoke(object, args); } /** * <p>Return an accessible method (that is, one that can be invoked via * reflection) with given name and a single parameter. If no such method * can be found, return <code>null</code>. * Basically, a convenience wrapper that constructs a <code>Class</code> * array for you.</p> * * @param clazz get method from this class * @param methodName get method with this name * @param parameterType taking this type of parameter */ public static Method getAccessibleMethod( Class clazz, String methodName, Class parameterType) { Class[] parameterTypes = {parameterType}; return getAccessibleMethod(clazz, methodName, parameterTypes); } /** * <p>Return an accessible method (that is, one that can be invoked via * reflection) with given name and parameters. If no such method * can be found, return <code>null</code>. * This is just a convenient wrapper for * {@link #getAccessibleMethod(Method method)}.</p> * * @param clazz get method from this class * @param methodName get method with this name * @param parameterTypes with these parameters types */ public static Method getAccessibleMethod( Class clazz, String methodName, Class[] parameterTypes) { try { MethodDescriptor md = new MethodDescriptor(clazz, methodName, parameterTypes, true); // Check the cache first Method method = (Method)cache.get(md); if (method != null) { return method; } method = getAccessibleMethod (clazz.getMethod(methodName, parameterTypes)); cache.put(md, method); return method; } catch (NoSuchMethodException e) { return (null); } } /** * <p>Return an accessible method (that is, one that can be invoked via * reflection) that implements the specified Method. If no such method * can be found, return <code>null</code>.</p> * * @param method The method that we wish to call */ public static Method getAccessibleMethod(Method method) { // Make sure we have a method to check if (method == null) { return (null); } // If the requested method is not public we cannot call it if (!Modifier.isPublic(method.getModifiers())) { return (null); } // If the declaring class is public, we are done Class clazz = method.getDeclaringClass(); if (Modifier.isPublic(clazz.getModifiers())) { return (method); } // Check the implemented interfaces and subinterfaces method = getAccessibleMethodFromInterfaceNest(clazz, method.getName(), method.getParameterTypes()); return (method); } // -------------------------------------------------------- Private Methods /** * <p>Return an accessible method (that is, one that can be invoked via * reflection) that implements the specified method, by scanning through * all implemented interfaces and subinterfaces. If no such method * can be found, return <code>null</code>.</p> * * <p> There isn't any good reason why this method must be private. * It is because there doesn't seem any reason why other classes should * call this rather than the higher level methods.</p> * * @param clazz Parent class for the interfaces to be checked * @param methodName Method name of the method we wish to call * @param parameterTypes The parameter type signatures */ private static Method getAccessibleMethodFromInterfaceNest (Class clazz, String methodName, Class parameterTypes[]) { Method method = null; // Search up the superclass chain for (; clazz != null; clazz = clazz.getSuperclass()) { // Check the implemented interfaces of the parent class Class interfaces[] = clazz.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { // Is this interface public? if (!Modifier.isPublic(interfaces[i].getModifiers())) continue; // Does the method exist on this interface? try { method = interfaces[i].getDeclaredMethod(methodName, parameterTypes); } catch (NoSuchMethodException e) { ; } if (method != null) break; // Recursively check our parent interfaces method = getAccessibleMethodFromInterfaceNest(interfaces[i], methodName, parameterTypes); if (method != null) break; } } // If we found a method return it if (method != null) return (method); // We did not find anything return (null); } /** * <p>Find an accessible method that matches the given name and has compatible parameters. * Compatible parameters mean that every method parameter is assignable from * the given parameters. * In other words, it finds a method with the given name * that will take the parameters given.<p> * * <p>This method is slightly undeterminstic since it loops * through methods names and return the first matching method.</p> * * <p>This method is used by * {@link * #invokeMethod(Object object,String methodName,Object [] args,Class[] parameterTypes)}. * * <p>This method can match primitive parameter by passing in wrapper classes. * For example, a <code>Boolean</code> will match a primitive <code>boolean</code> * parameter. * * @param clazz find method in this class * @param methodName find method with this name * @param parameterTypes find method with compatible parameters */ public static Method getMatchingAccessibleMethod( Class clazz, String methodName, Class[] parameterTypes) { MethodDescriptor md = new MethodDescriptor(clazz, methodName, parameterTypes, false); // see if we can find the method directly // most of the time this works and it's much faster try { // Check the cache first Method method = (Method)cache.get(md);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -