我知道如何创建一个有String参数并返回int的方法的引用,它是:
Function<String, Integer>
然而,如果函数抛出异常,比如它被定义为:
Integer myMethod(String s) throws IOException
我该如何定义这个引用呢?
我知道如何创建一个有String参数并返回int的方法的引用,它是:
Function<String, Integer>
然而,如果函数抛出异常,比如它被定义为:
Integer myMethod(String s) throws IOException
我该如何定义这个引用呢?
当前回答
我会做一些一般的事情:
public interface Lambda {
@FunctionalInterface
public interface CheckedFunction<T> {
T get() throws Exception;
}
public static <T> T handle(CheckedFunction<T> supplier) {
try {
return supplier.get();
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
}
用法:
Lambda.handle(() -> method());
其他回答
如果您不介意使用第三方库,使用cyclops-react(我贡献的一个库),您可以使用FluentFunctions API来编写
Function<String, Integer> standardFn = FluentFunctions.ofChecked(this::myMethod);
ofChecked接受jOOλ CheckedFunction,并将软化后的引用返回到标准(未选中)JDK java.util.function.Function。
或者,你可以通过FluentFunctions api继续使用捕获的函数!
例如,要执行你的方法,最多重试5次,并记录你可以写入的状态
FluentFunctions.ofChecked(this::myMethod)
.log(s->log.debug(s),e->log.error(e,e.getMessage())
.try(5,1000)
.apply("my param");
如果你有lombok,你可以用@SneakyThrows注释你的方法
SneakyThrow不会静默地吞咽、包装到RuntimeException中,或以其他方式修改所列出的检查异常类型的任何异常。JVM不检查被检查异常系统的一致性;Javac可以,而且这个注释允许您选择不使用它的机制。
https://projectlombok.org/features/SneakyThrows
使用Function包装器的另一种解决方案是返回结果包装器的实例,如果一切正常,则返回成功,或者返回失败。
一些代码来澄清事情:
public interface ThrowableFunction<A, B> {
B apply(A a) throws Exception;
}
public abstract class Try<A> {
public static boolean isSuccess(Try tryy) {
return tryy instanceof Success;
}
public static <A, B> Function<A, Try<B>> tryOf(ThrowableFunction<A, B> function) {
return a -> {
try {
B result = function.apply(a);
return new Success<B>(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<A> extends Try<A> {
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<A> extends Try<A> {
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;
}
}
一个简单的用例:
List<Try<Integer>> result = Lists.newArrayList(1, 2, 3).stream().
map(Try.<Integer, Integer>tryOf(i -> someMethodThrowingAnException(i))).
collect(Collectors.toList());
这并不是Java 8所特有的。你正在尝试编译一些等价的东西:
interface I {
void m();
}
class C implements I {
public void m() throws Exception {} //can't compile
}
我是一个小库的作者,它具有一些通用的魔法,可以在任何地方抛出任何Java异常,而不需要捕获它们,也不需要将它们包装到RuntimeException中。
用法: unchecked(() -> methodThrowingCheckedException())
public class UncheckedExceptions {
/**
* throws {@code exception} as unchecked exception, without wrapping exception.
*
* @return will never return anything, return type is set to {@code exception} only to be able to write <code>throw unchecked(exception)</code>
* @throws T {@code exception} as unchecked exception
*/
@SuppressWarnings("unchecked")
public static <T extends Throwable> T unchecked(Exception exception) throws T {
throw (T) exception;
}
@FunctionalInterface
public interface UncheckedFunction<R> {
R call() throws Exception;
}
/**
* Executes given function,
* catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
*
* @return result of function
* @see #unchecked(Exception)
*/
public static <R> R unchecked(UncheckedFunction<R> function) {
try {
return function.call();
} catch (Exception e) {
throw unchecked(e);
}
}
@FunctionalInterface
public interface UncheckedMethod {
void call() throws Exception;
}
/**
* Executes given method,
* catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
*
* @see #unchecked(Exception)
*/
public static void unchecked(UncheckedMethod method) {
try {
method.call();
} catch (Exception e) {
throw unchecked(e);
}
}
}
来源:https://github.com/qoomon/unchecked-exceptions-java