【问题标题】:How to instantiate an object using LambdaMetaFactory?如何使用 LambdaMetaFactory 实例化对象?
【发布时间】:2018-12-07 19:31:34
【问题描述】:

我有一个界面Action:

package action;

public interface Action {
    public String act();
}

类 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;
    }
}

类 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;
        }
    }

我想创建一个函数,它采用类的名称并返回该类的对象。 这就是我迄今为止在我的职能中所拥有的 -

 

    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));
    }

【问题讨论】:

    标签: java lambda java-8 invokedynamic lambda-metafactory


    【解决方案1】:

    想通了。

    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】:

      你可以这样做,它会给你一个对象,使用不带参数的构造函数:

      public static Object resultOfActMethod(String objclass) 
          throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<?> clazz = Class.forName(objclass);
        return clazz.getConstructor().newInstance();
      }
      

      但如果可能在你的应用程序中,你应该创建一个函数来代替这样的类:

      public static <C> C resultOfActMethod(Class<C> clazz) 
          throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        return clazz.getConstructor().newInstance();
      }
      

      这是类型安全的。您可以使用特定的返回类型。这将避免在调用方进行类型转换。

      【讨论】:

      • 引用 Java 文档 我认为使用这种方法并不明智。 javadoc特别指出“使用此方法有效地绕过编译时异常检查,否则编译器将执行该异常检查。Constructor.newInstance 方法通过将构造函数抛出的任何异常包装在(检查的)InvocationTargetException 中来避免此问题。”
      • 感谢 Google、StackOverflow 和一些研究,我得以解决它。我在下面发布了我的答案。
      • 本题发帖者特意求LambdaMetafactory相关的答案,不应该给出标准的反射例子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-28
      • 1970-01-01
      • 1970-01-01
      • 2013-04-19
      相关资源
      最近更新 更多