问题
I have an interface Action:
package action;
public interface Action {
public String act();
}
Class SimpleAction:
package action;
public class SimpleAction implements Action {
String action;
public SimpleAction() {}
public SimpleAction(String x) {
this.action = x;
}
@Override
public String act() {
return "Act method from -" + this.action;
}
}
Class ComplexAction:
package action;
public class ComplexAction implements Action{
String action;
public ComplexAction() {}
public ComplexAction(String x) {
this.action = x;
}
@Override
public String act() {
return "Act method from -" + this.action;
}
}
I want to create a function which takes the name of class and returns an object of that class. This is what I have so far in my function -
public static Action resultOfActMethod(String objclass){
Class clazz = Class.forName(objclass);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findConstructor(clazz,MethodType.methodType(void.class, String.class));
}
回答1:
Figured it out.
public static Action resultOfActMethod(String objclass){
Class clazz = Class.forName(objclass);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findConstructor(clazz, MethodType.methodType(void.class, String.class));
Function<String, Action> constructor = (Function<String, Action>)LambdaMetafactory.metafactory(lookup, "apply",MethodType.methodType(Function.class),
mh.type().generic(), mh, mh.type()).getTarget().invokeExact();
Action action = constructor.apply(objclass);
return action;
}
回答2:
You can do just this, it will give you an object, using the constructor with no arguments:
public static Object resultOfActMethod(String objclass)
throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<?> clazz = Class.forName(objclass);
return clazz.getConstructor().newInstance();
}
But if possible in your application, you should make a function which takes a class instead like this:
public static <C> C resultOfActMethod(Class<C> clazz)
throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
return clazz.getConstructor().newInstance();
}
This is typesafe. You can use a specific return type. This will avoid a type cast at the caller's side.
来源:https://stackoverflow.com/questions/53675777/how-to-instantiate-an-object-using-lambdametafactory