我有以下代码
public class FunctionalInterfaceTest {
@FunctionalInterface
public interface FunctionThatThrows<T, R> {
R apply(T t) throws Exception;
}
public void perform() {
try {
unchecked((String x) -> Integer.parseInt(x)).apply("abc");
} catch (Exception e) {
System.out.println("Encountered exception" + e.getMessage());
}
}
public void perform1() {
try {
unchecked(<fill-in-here-using-method-reference>);
} catch (Exception e) {
System.out.println("Encountered Exception" + e.getMessage());
}
}
public <T, R> Function<T, R> unchecked(FunctionThatThrows<T, R> f) {
return (a) -> {
try {
return f.apply(a);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
}
public static void main(String[] args) {
FunctionalInterfaceTest test = new FunctionalInterfaceTest();
test.perform();
test.perform1();
}
}
我想在perform1方法中使用方法参考来获得与perform方法相似的结果。我尝试在perform1中使用诸如Integer :: parseInt之类的方法引用,但是它不起作用。如何对方法引用进行相同操作,为什么该方法引用会出现错误?
答案 0 :(得分:1)
我如何对方法引用进行相同操作,为什么该方法引用会出现错误?
您不能,除非存在显式类型。由于unchecked
方法使用通用参数FunctionThatThrows<T, R>
,因此编译器不知道这些通用类型T
和R
是什么。以下内容将无法编译:
unchecked(s -> Integer.parseInt(s)); // doesn't compile
编译器认为s
是与Integer.parseInt(String s)
方法不兼容的Object
。这就是为什么它含糊不清的原因。
重点是,必须明确声明泛型参数的类型。可以使用三种方法来定义类型并保留通用解决方案。
已经完成,使用向下转换将s
指定为String
。
unchecked((String x) -> Integer.parseInt(x)) // no method reference
对所传递的lambda表达式进行显式转换。该解决方案是IntelliJ Idea向我提供的第一个解决方案。现在很清楚,传递给函数的编译器输入和输出分别为String
和Integer
。请注意,此结构是Integer.parseInt(String s)
要求的`:
unchecked((FunctionThatThrows<String, Integer>) Integer::parseInt); // with method reference
明确定义所需的返回类型:
Function<String, Integer> f = unchecked((FunctionThatThrows<String, Integer>) Integer::parseInt);
..应该省略多余的转换,它会给出更清晰的结果:
Function<String, Integer> f = unchecked(Integer::parseInt); // with method reference