Java:当方法参数为另一类实例时调用该方法
Alright, let's tackle this problem step by step. Here's how you can achieve what you're looking for using Java reflection:
Key Pre-Requisite Note
First off: if you're targeting private methods like your example onEvent(ExampleEvent), the standard getMethods() won't work—it only returns public methods (including inherited ones). Instead, use getDeclaredMethods() to grab all methods declared in the class, regardless of their access modifier.
Step-by-Step Solution
1. Define Your Base and Event Classes
Let's start with the foundational classes we'll work with:
// Base Event class class Event {} // A subclass of Event class ExampleEvent extends Event {} // The class containing our target methods class EventHandler { private void onEvent(ExampleEvent event) { System.out.println("Successfully handled ExampleEvent: " + event.toString()); } // Extra methods to test our filtering logic public void nonEventMethod(String input) {} private void multiParamMethod(int id, Event event) {} }
2. Reflection Logic to Find and Invoke Target Methods
Here's the core code to scan for methods with a single Event (or subclass) parameter and call them:
import java.lang.reflect.Method; public class EventInvoker { public static void main(String[] args) { // Create an instance of the class we're inspecting EventHandler handlerInstance = new EventHandler(); Class<?> handlerClass = handlerInstance.getClass(); // Grab all declared methods (including private ones) Method[] allMethods = handlerClass.getDeclaredMethods(); for (Method method : allMethods) { // Filter: only keep methods with exactly 1 parameter Class<?>[] paramTypes = method.getParameterTypes(); if (paramTypes.length != 1) { continue; } Class<?> paramType = paramTypes[0]; // Check if the parameter is Event or a subclass of Event if (Event.class.isAssignableFrom(paramType)) { try { // Create an instance of the Event subclass (assumes no-arg constructor exists) Object eventInstance = paramType.getDeclaredConstructor().newInstance(); // Bypass access checks for private methods method.setAccessible(true); // Invoke the method with the event instance method.invoke(handlerInstance, eventInstance); // Optional: Reset accessibility if you don't need to call it again method.setAccessible(false); } catch (Exception e) { // Handle specific exceptions based on your use case System.err.println("Failed to invoke method " + method.getName() + ": " + e.getMessage()); } } } } }
3. Key Details to Keep in Mind
isAssignableFromvsinstanceof: We useEvent.class.isAssignableFrom(paramType)because it checks ifparamTypeis a subclass (or the same class) asEvent—perfect for your requirement of matching anyEventinstance/subclass.- Handling Non-No-Arg Constructors: If your
Eventsubclass doesn't have a no-argument constructor, you'll need to locate the correct constructor and pass required arguments. For example:// If ExampleEvent has a constructor like ExampleEvent(String eventId) Constructor<?> constructor = paramType.getDeclaredConstructor(String.class); Object eventInstance = constructor.newInstance("test-event-123"); - Exception Handling: The example uses a broad
Exceptioncatch for simplicity, but in production code, catch specific exceptions likeNoSuchMethodException,IllegalAccessException, orInvocationTargetException(which wraps exceptions thrown inside the target method). - Inherited Methods:
getDeclaredMethods()only returns methods declared in the current class. If you need to scan inherited methods too, you'll need to recursively traverse the class hierarchy usinggetSuperclass().
内容的提问来源于stack exchange,提问作者Lakloth
相关产品推荐
相关产品推荐

