Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
来自模板化对象的Java 8函数构造函数_Java_Eclipse_Generics_Functional Programming_Java 8 - Fatal编程技术网

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

来自模板化对象的Java 8函数构造函数,java,eclipse,generics,functional-programming,java-8,Java,Eclipse,Generics,Functional Programming,Java 8,我正在使用EclipseLuna服务版本2(4.4.2),Java8U51 我正在尝试创建一个方法,该方法将基于另一个方法参数创建已传递对象的实例。原型简化为 public <T> T test(Object param, T instance) { Constructor<?> constructor = instance.getClass().getConstructors()[0]; // I actually choose a proper constru

我正在使用EclipseLuna服务版本2(4.4.2),Java8U51

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

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;
}
publicttest(对象参数,T实例){
构造函数Constructor=instance.getClass().getConstructors()[0];//我实际上选择了一个合适的构造函数
//eclipse报告“未处理的异常类型InvocationTargetException”
函数createFun=constructor::newInstance;
T result=(T)createFun.apply(param);
返回结果;
}
联机使用
函数
声明eclipse报告
未处理的异常类型InvocationTargetException
编译器错误。我需要
函数
,以便以后在流中使用

我试图添加各种try/catch块,抛出声明,但没有任何东西修复这个编译器错误


如何使此代码工作?

您不能使用
函数
目标类型从lambda抛出已检查的异常,因为其
应用
方法不会抛出异常。因此,您需要将其转换为未经检查的异常,例如通过包装:

Function<Object, Object> createFun = o -> {
  try {
    return constructor.newInstance(o);
  } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
    throw new RuntimeException(e);
  }
};
函数createFun=o->{
试一试{
返回构造函数newInstance(o);
}catch(实例化异常|调用目标异常|非法访问异常e){
抛出新的运行时异常(e);
}
};
另一种方法是让编译器认为这是未经检查的异常,与上面的选项相比,它会生成更干净的堆栈跟踪:

Function<Object, Object> createFun = o -> {
  try {
    return constructor.newInstance(o);
  } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
    return uncheck(e);
  }
};
函数createFun=o->{
试一试{
返回构造函数newInstance(o);
}catch(实例化异常|调用目标异常|非法访问异常e){
返回取消选中(e);
}
};
使用以下实用方法:

@SuppressWarnings("unchecked")
public static <E extends Throwable, T> T uncheck(Throwable t) throws E {
  throw ((E) t);
}
@SuppressWarnings(“未选中”)
公共静态T取消选中(可丢弃T)抛出E{
投掷((E)t);
}

这是因为方法引用的是编译时错误中指定的异常的方法。单一抽象方法
R适用(T T
)在
java.util.Function
不会抛出这些异常。因此,java.util.Function的函数类型与方法引用的类型不匹配

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

    interface MyFunction<T,R> {
        /**
         * Applies this function to the given argument.
         *
         * @param t the function argument
         * @return the function result
         */
        R apply(T t) throws  Throwable;

    }

    public <T> 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<Object,Object> createFun = constructor::newInstance;

        T result = (T) createFun.apply(param);
        return result;
    }
接口函数{
/**
*将此函数应用于给定参数。
*
*@param t函数参数
*@返回函数结果
*/
R应用(T)可丢弃;
}
公共T测试(对象参数,T实例)抛出实例化异常、IllegalAccessException、,
IllegalArgumentException,InvocationTargetException{
构造函数Constructor=instance.getClass().getConstructors()[0];//我实际上选择了一个合适的构造函数
//eclipse报告“未处理的异常类型InvocationTargetException”
MyFunction createFun=构造函数::newInstance;
T result=(T)createFun.apply(param);
返回结果;
}

您可以从lambda抛出选中的异常。但不是来自应该实现函数的lambda,因为Function.apply()不会引发选中的异常。您可以通过引入
绑定来收紧
取消选中的
方法,这样您就不必进行任何类型的强制转换。您也可以在
取消选中
方法的内部执行抛出操作;当你可以只使用一个方法时,不需要两个方法。你认为
函数
绕道比在
构造函数
上简单调用
newInstance
有什么好处?@Holger我在流中使用
newInstance
构造函数
上,它产生了相同的消息,所以我创建了一个这样的SSCE。函数detour实际上是保持相对可读的
stream()
链所必需的。我明白了。因此,对于用例和lambda表达式,assylias建议的应该可以工作,这有点过于简单了。但我现在想知道的是,对于结果类型是否是
实例
(可能是
T
的子类)的确切类型,是否真的有严格的要求,换句话说,诉诸反射是否真的有必要…@Holger我找不到无反射的解决方案。该方法确实用于T的许多子类。我想要一个具有清晰定义但可能具有丑陋但单一实现的方法。我最终传递了一个
类,而不是T的一个实例。如果在调用方的站点上有一个已知的具体类型,则可以使用类似
Function f=B::new的构造应该是可能的。如果调用方本身是泛型的,那么工作起来就不那么容易了,但是它必须从某处获取
对象,不是吗?也许有一个无反射的解决方案,但这似乎值得打开另一个问题(关于用例的更多信息)…