本文共 5351 字,大约阅读时间需要 17 分钟。
本文翻译自:
I know how to create a reference to a method that has a String
parameter and returns an int
, it's: 我知道如何创建对具有String
参数并返回int
的方法的引用,它是:
Function
However, this doesn't work if the function throws an exception, say it's defined as: 但是,如果该函数引发异常,则将其定义为:
Integer myMethod(String s) throws IOException
How would I define this reference? 我将如何定义此参考?
参考:
Disclaimer: I haven't used Java 8 yet, only read about it. 免责声明:我还没有使用Java 8,只阅读过它。
Function<String, Integer>
doesn't throw IOException
, so you can't put any code in it that throws IOException
. Function<String, Integer>
不会引发IOException
,因此您不能在其中放入任何throws IOException
代码。 If you're calling a method that expects a Function<String, Integer>
, then the lambda that you pass to that method can't throw IOException
, period. 如果调用的方法需要Function<String, Integer>
,则传递给该方法的lambda不能抛出IOException
,period。 You can either write a lambda like this (I think this is the lambda syntax, not sure): 您可以这样编写一个lambda(我不确定这是lambda语法):
(String s) -> { try { return myMethod(s); } catch (IOException ex) { throw new RuntimeException(ex); // (Or do something else with it...) }}
Or, if the method you're passing the lambda to is one you wrote yourself, you can define a new functional interface and use that as the parameter type instead of Function<String, Integer>
: 或者,如果将lambda传递给您的方法是您自己编写的,则可以定义一个新的函数接口,并将其用作参数类型,而不是Function<String, Integer>
:
public interface FunctionThatThrowsIOException { O apply(I input) throws IOException;}
You'll need to do one of the following. 您需要执行以下操作之一。
If it's your code, then define your own functional interface that declares the checked exception: 如果是您的代码,请定义自己的函数接口,该接口声明已检查的异常:
@FunctionalInterface public interface CheckedFunction{ R apply(T t) throws IOException; }
and use it: 并使用它:
void foo (CheckedFunction f) { ... }
Otherwise, wrap Integer myMethod(String s)
in a method that doesn't declare a checked exception: 否则,将Integer myMethod(String s)
包装在未声明检查异常的方法中:
public Integer myWrappedMethod(String s) { try { return myMethod(s); } catch(IOException e) { throw new UncheckedIOException(e); } }
and then: 接着:
Functionf = (String t) -> myWrappedMethod(t);
or: 要么:
Functionf = (String t) -> { try { return myMethod(t); } catch(IOException e) { throw new UncheckedIOException(e); } };
This is not specific to Java 8. You are trying to compile something equivalent to: 这不是特定于Java 8的。您尝试编译的内容等同于:
interface I { void m();}class C implements I { public void m() throws Exception {} //can't compile}
Another solution using a Function wrapper would be to return either an instance of a wrapper of your result, say Success, if everything went well, either an instance of, say Failure. 使用函数包装的另一种解决方案是,如果一切顺利,则返回结果包装的一个实例,即成功;如果失败,则返回一个实例。
Some code to clarify things : 一些代码来澄清事情:
public interface ThrowableFunction { B apply(A a) throws Exception;}public abstract class Try { public static boolean isSuccess(Try tryy) { return tryy instanceof Success; } public static Function > tryOf(ThrowableFunction function) { return a -> { try { B result = function.apply(a); return new Success (result); } catch (Exception e) { return new Failure<>(e); } }; } public abstract boolean isSuccess(); public boolean isError() { return !isSuccess(); } public abstract A getResult(); public abstract Exception getError();}public class Success extends Try { private final A result; public Success(A result) { this.result = result; } @Override public boolean isSuccess() { return true; } @Override public A getResult() { return result; } @Override public Exception getError() { return new UnsupportedOperationException(); } @Override public boolean equals(Object that) { if(!(that instanceof Success)) { return false; } return Objects.equal(result, ((Success) that).getResult()); }}public class Failure extends Try { private final Exception exception; public Failure(Exception exception) { this.exception = exception; } @Override public boolean isSuccess() { return false; } @Override public A getResult() { throw new UnsupportedOperationException(); } @Override public Exception getError() { return exception; }}
A simple use case : 一个简单的用例:
List> result = Lists.newArrayList(1, 2, 3).stream(). map(Try. tryOf(i -> someMethodThrowingAnException(i))). collect(Collectors.toList());
What I'm doing is to allow the user to give the value he actually want in case of exception . 我正在做的是允许用户在异常情况下提供他实际想要的值。 So I've something looking like this 所以我看起来像这样
public staticFunction defaultIfThrows(FunctionThatThrows delegate, R defaultValue) { return x -> { try { return delegate.apply(x); } catch (Throwable throwable) { return defaultValue; } };}@FunctionalInterfacepublic interface FunctionThatThrows { R apply(T t) throws Throwable;}
And this can then be call like : 然后可以这样调用:
defaultIfThrows(child -> child.getID(), null)
转载地址:http://bfexb.baihongyu.com/