来自模板化对象的Java 8函数构造函数

Dar*_*usz 6 java eclipse generics functional-programming java-8

我正在使用Eclipse Luna Service Release 2(4.4.2),Java 8 u51.

我正在尝试创建一个方法,该方法将基于另一个方法参数创建传递对象的实例.原型简化为

public <T> T test(Object param, T instance) {
    Constructor<?> constructor = instance.getClass().getConstructors()[0]; // I actually choose a proper constructor

    // eclipse reports "Unhandled exception type InvocationTargetException"
    Function<Object, Object> createFun = constructor::newInstance;

    T result = (T) createFun.apply(param);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

在线Function声明eclipse报告Unhandled exception type InvocationTargetException编译器错误.我需要Function稍后在流中使用.

我试图添加各种try/catch块,抛出声明,但没有修复此编译器错误.

如何使这段代码工作?

ass*_*ias 11

您不能从具有Function目标类型的lambda抛出已检查的异常,因为它的apply方法不会抛出异常.因此,您需要将其设置为未经检查的异常,例如通过包装它:

Function<Object, Object> createFun = o -> {
  try {
    return constructor.newInstance(o);
  } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
    throw new RuntimeException(e);
  }
};
Run Code Online (Sandbox Code Playgroud)

另一种方法是引导编译器认为它是一个未经检查的异常,与上面的选项产生更清晰的堆栈跟踪:

Function<Object, Object> createFun = o -> {
  try {
    return constructor.newInstance(o);
  } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
    return uncheck(e);
  }
};
Run Code Online (Sandbox Code Playgroud)

使用以下实用方法:

@SuppressWarnings("unchecked")
public static <E extends Throwable, T> T uncheck(Throwable t) throws E {
  throw ((E) t);
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以从lambda中抛出已检查的异常.但不是来自应该实现Function的lambda,因为Function.apply()不会抛出一个已检查的异常. (3认同)
  • 您可以通过引入`<T extends Throwable>`绑定来收紧`uncheck`方法,这样您就不必进行任何类型的转换.你也可以在`uncheck`方法中执行你的抛出; 当你可以投入一个时,不需要两种方法. (2认同)