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

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

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

public  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 createFun = constructor::newInstance; T result = (T) createFun.apply(param); return result; } 

Function声明一致的eclipse报告Unhandled exception type InvocationTargetException编译器错误。 我需要Function以后在流中使用。

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

如何使这段代码工作?

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

 Function createFun = o -> { try { return constructor.newInstance(o); } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); } }; 

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

 Function createFun = o -> { try { return constructor.newInstance(o); } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { return uncheck(e); } }; 

使用以下实用方法:

 @SuppressWarnings("unchecked") public static  T uncheck(Throwable t) throws E { throw ((E) t); } 

这是因为方法引用是一个带有编译时错误中指定的exception的方法。 java.util.Function中的单个抽象方法R apply(T t )不会抛出这些exception。 因此,java.util.Function的函数类型与Method-Reference的类型不匹配。

使用具有匹配方法的函数类型可以…例如:

  interface MyFunction { /** * Applies this function to the given argument. * * @param t the function argument * @return the function result */ R apply(T t) throws Throwable; } public  T test(Object param, T instance) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Constructor constructor = instance.getClass().getConstructors()[0]; // I actually choose a proper constructor // eclipse reports "Unhandled exception type InvocationTargetException" MyFunction createFun = constructor::newInstance; T result = (T) createFun.apply(param); return result; }