Reputation: 1813
I am trying to write a method that takes in 2 parameters - a class reference, and a reference of a method in that class. The return type of the method itself should be whatever that class's method return type is. For example:
public <T> T myMethod (Class<?> c, <reference to a method m in class c>), where m returns something of type <T>.
That is, in my code I should be able to call the above method as:
myMethod (SomeClass.class, x -> x.someMethod(param1, param2))
Note that SomeClass
can be any class, and someMethod
can be any method in that class with any number of parameters.
I am reasonably sure this is possible using lambda and functional interface in Java 8, but not entire clear on how to put it.
Upvotes: 1
Views: 12321
Reputation: 159096
The functional interface method needs to take one argument of the same type as the named class c
, so you need to define a generic type for that class, lets call it C
.
The functional interface method needs to return a value of type T
, but lets rename it R
to represent the return type.
This means that your function interface can be: Function<C, R>
Your full method declaration is then:
public <C, R> R myMethod(Class<? extends C> clazz, Function<C, R> method)
It can be called exactly like you showed.
Demo
public class Test {
public static void main(String[] args) throws Exception {
Test t = new Test();
String param1 = "Foo", param2 = "Bar";
String result = t.myMethod(SomeClass.class, x -> x.someMethod(param1, param2));
System.out.println(result);
}
public <C, R> R myMethod(Class<? extends C> clazz, Function<C, R> method) throws Exception {
C obj = clazz.getConstructor().newInstance();
return method.apply(obj);
}
}
class SomeClass {
public SomeClass() {}
public String someMethod(String param1, String param2) {
return param1 + " + " + param2 + ": " + this;
}
}
Output
Foo + Bar: test.SomeClass@5594a1b5
Upvotes: 10
Reputation: 1261
What you are trying to do isn't immediately possible. Meaning, you can't reference a method without having a direct reflective access to it.
Effectively, myMethod(MyClass.class, myClass -> myClass.Hello)
is definitely not
a good solution to anything. Think about it, where would you need this? If the method was static, you could invoke it anyways, and if it wasn't, you'd only need an instance.
What you can do, however, is find your method and invoke it through the reflection api:
public Object myMethod(Class<?> clazz) {
return clazz.getDeclaredMethod("name_of_method", ... /*Any parameters*/).invoke(/*params*/);
}
Upvotes: 0