vendredi 27 mars 2015

Invoke a method from another class with multiple parameters (all generically)

I've just started working with reflection and generic types today for a project I am working on. What I am attempting to do with these is to invoke methods from other classes with varying parameters (all using generic types), but I'm not sure if what I'm looking for is possible.


Let's say I have the following class, SceneHandler, and my class, LoginScene, runs a method in the handler class with CreateHandle(this.getClass(), "test", 1);.


As a reference, here is the SceneHandler class I've started on:



public class SceneHandler
{
public static <T1, T2> EventHandler<ActionEvent> CreateHandle(final Class<T1> target, final String methodName, final T2... args)
{
return new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent e)
{
Method method = null;
try
{
method = target.getDeclaredMethod(methodName, args.getClass());
}
catch (Exception ex)
{
System.out.println("Failed to get declared method.");
ex.printStackTrace();
}
try
{
if (method != null)
method.invoke(target, args);
}
catch (Exception ex)
{
System.out.println("Invocation failed on Event Handler.");
ex.printStackTrace();
}
}
};
}
}


As well as the LoginScene class:



public class LoginScene extends Scene
{
public LoginScene()
{
super(loginPane, Game.DEFAULT_WIDTH, Game.DEFAULT_HEIGHT);

Button loginButton = new Button("Login");
EventHandler<ActionEvent> loginHandle = LoginSceneHandler.CreateHandle(this.getClass(), "test", 0);
loginButton.setOnAction(loginHandle);
}

public static void test(int i)
{
System.out.println("The integer given was " + i);
}
}


Now in the SceneHandler, we know which class called us with the T1 type we are given (in this case, it is LoginScene), we do know the name of the method is a string, but we do not know what arguments/argument types are going to be presented.


With that being said, I am getting the following error:



java.lang.NoSuchMethodException: edelong.game.client.scenes.LoginScene.test([Ljava.lang.Integer;)


If I remove the "..." from the T2... args, and change the public void test(int) to a public void test(Integer), it works. Is there a way to make Integers work the same as ints? Or do I have to cast (int) in the function.


Additionally, is there a way to make this work with multiple arguments? I'm not sure how to pass through a "list" of parameter-types with generics.


Thank you in advance for any feedback.






Aucun commentaire:

Enregistrer un commentaire