String
パラメータを持ち、を返すメソッドへの参照を作成する方法を知っていますint
。
Function<String, Integer>
ただし、関数が例外をスローする場合、これは機能しません。たとえば、次のように定義されているとします。
Integer myMethod(String s) throws IOException
この参照をどのように定義しますか?
String
パラメータを持ち、を返すメソッドへの参照を作成する方法を知っていますint
。
Function<String, Integer>
ただし、関数が例外をスローする場合、これは機能しません。たとえば、次のように定義されているとします。
Integer myMethod(String s) throws IOException
この参照をどのように定義しますか?
回答:
次のいずれかを行う必要があります。
コードの場合は、チェックされた例外を宣言する独自の機能インターフェイスを定義します。
@FunctionalInterface
public interface CheckedFunction<T, R> {
R apply(T t) throws IOException;
}
そしてそれを使う:
void foo (CheckedFunction f) { ... }
それ以外の場合はInteger myMethod(String s)
、チェック済み例外を宣言しないメソッドでラップします。
public Integer myWrappedMethod(String s) {
try {
return myMethod(s);
}
catch(IOException e) {
throw new UncheckedIOException(e);
}
}
その後:
Function<String, Integer> f = (String t) -> myWrappedMethod(t);
または:
Function<String, Integer> f =
(String t) -> {
try {
return myMethod(t);
}
catch(IOException e) {
throw new UncheckedIOException(e);
}
};
Consumer
もFunction
、デフォルトの方法を使用することもできます-以下の私の答えを参照してください。
(String t) -> myWrappedMethod(t)
、メソッドリファレンスthis::myWrappedMethod
を使用することもできます。
Java 8のデフォルトメソッドを使用して、例外を処理する新しいインターフェースで実際に拡張Consumer
(Function
など)できます。
このインターフェースを検討してください(拡張Consumer
):
@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {
@Override
default void accept(final T elem) {
try {
acceptThrows(elem);
} catch (final Exception e) {
// Implement your own exception handling logic here..
// For example:
System.out.println("handling an exception...");
// Or ...
throw new RuntimeException(e);
}
}
void acceptThrows(T elem) throws Exception;
}
次に、たとえば、リストがある場合:
final List<String> list = Arrays.asList("A", "B", "C");
forEach
例外をスローするいくつかのコードでそれを(例えばで)消費したい場合、伝統的にtry / catchブロックを設定します:
final Consumer<String> consumer = aps -> {
try {
// maybe some other code here...
throw new Exception("asdas");
} catch (final Exception ex) {
System.out.println("handling an exception...");
}
};
list.forEach(consumer);
しかし、この新しいインターフェースを使用すると、ラムダ式でインスタンス化でき、コンパイラーは文句を言いません:
final ThrowingConsumer<String> throwingConsumer = aps -> {
// maybe some other code here...
throw new Exception("asdas");
};
list.forEach(throwingConsumer);
または、キャストしてさらに簡潔にすることもできます!:
list.forEach((ThrowingConsumer<String>) aps -> {
// maybe some other code here...
throw new Exception("asda");
});
更新:エラーと呼ばれるDurianの非常に優れたユーティリティライブラリの一部があるようです。このライブラリを使用すると、この問題をより柔軟に解決できます。たとえば、上記の実装では、エラー処理ポリシー(または)を明示的に定義しましたが、Durianのエラーを使用すると、ユーティリティメソッドの大規模なスイートを介してオンザフライでポリシーを適用できます。それを共有してくれてありがとう、@ NedTwigg!。System.out...
throw RuntimeException
使用例:
list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));
ドリアンのErrors
クラスは、上記のさまざまな提案の多くの長所を組み合わせていると思います。
ドリアンをプロジェクトに含めるには、次のいずれかを行います。
com.diffplug.durian:durian:3.3.0
Throwing.java
とErrors.java
これはJava 8に固有のものではありません。以下と同等のものをコンパイルしようとしています。
interface I {
void m();
}
class C implements I {
public void m() throws Exception {} //can't compile
}
免責事項:私はまだJava 8を使用していません。読むだけです。
Function<String, Integer>
はスローしないIOException
ので、その中にコードを入れることはできませんthrows IOException
。を必要とするメソッドを呼び出してFunction<String, Integer>
いる場合、そのメソッドに渡すラムダはIOException
、ピリオドをスローできません。次のようなラムダを書くこともできます(これはラムダ構文だと思いますが、わかりません):
(String s) -> {
try {
return myMethod(s);
} catch (IOException ex) {
throw new RuntimeException(ex);
// (Or do something else with it...)
}
}
または、ラムダを渡すメソッドが自分で作成したものである場合は、新しい関数インターフェイスを定義して、次の代わりにそれをパラメータータイプとして使用できますFunction<String, Integer>
。
public interface FunctionThatThrowsIOException<I, O> {
O apply(I input) throws IOException;
}
@FunctionalInterface
注釈をラムダで使用できるようにする必要はありません。ただし、健全性チェックにはお勧めです。
ただし、以下のようにスローする独自のFunctionalInterfaceを作成できます。
@FunctionalInterface
public interface UseInstance<T, X extends Throwable> {
void accept(T instance) throws X;
}
次に、以下に示すように、ラムダまたは参照を使用して実装します。
import java.io.FileWriter;
import java.io.IOException;
//lambda expressions and the execute around method (EAM) pattern to
//manage resources
public class FileWriterEAM {
private final FileWriter writer;
private FileWriterEAM(final String fileName) throws IOException {
writer = new FileWriter(fileName);
}
private void close() throws IOException {
System.out.println("close called automatically...");
writer.close();
}
public void writeStuff(final String message) throws IOException {
writer.write(message);
}
//...
public static void use(final String fileName, final UseInstance<FileWriterEAM, IOException> block) throws IOException {
final FileWriterEAM writerEAM = new FileWriterEAM(fileName);
try {
block.accept(writerEAM);
} finally {
writerEAM.close();
}
}
public static void main(final String[] args) throws IOException {
FileWriterEAM.use("eam.txt", writerEAM -> writerEAM.writeStuff("sweet"));
FileWriterEAM.use("eam2.txt", writerEAM -> {
writerEAM.writeStuff("how");
writerEAM.writeStuff("sweet");
});
FileWriterEAM.use("eam3.txt", FileWriterEAM::writeIt);
}
void writeIt() throws IOException{
this.writeStuff("How ");
this.writeStuff("sweet ");
this.writeStuff("it is");
}
}
あなたはできる。
@marcgを拡張し、必要に応じUtilException
てジェネリック<E extends Exception>
を追加します。これにより、コンパイラーは、Java 8のストリームでネイティブにチェック済み例外をスローできるかのように、もう一度スロー句とすべてを強制的に追加します。
public final class LambdaExceptionUtil {
@FunctionalInterface
public interface Function_WithExceptions<T, R, E extends Exception> {
R apply(T t) throws E;
}
/**
* .map(rethrowFunction(name -> Class.forName(name))) or .map(rethrowFunction(Class::forName))
*/
public static <T, R, E extends Exception> Function<T, R> rethrowFunction(Function_WithExceptions<T, R, E> function) throws E {
return t -> {
try {
return function.apply(t);
} catch (Exception exception) {
throwActualException(exception);
return null;
}
};
}
@SuppressWarnings("unchecked")
private static <E extends Exception> void throwActualException(Exception exception) throws E {
throw (E) exception;
}
}
public class LambdaExceptionUtilTest {
@Test
public void testFunction() throws MyTestException {
List<Integer> sizes = Stream.of("ciao", "hello").<Integer>map(rethrowFunction(s -> transform(s))).collect(toList());
assertEquals(2, sizes.size());
assertEquals(4, sizes.get(0).intValue());
assertEquals(5, sizes.get(1).intValue());
}
private Integer transform(String value) throws MyTestException {
if(value==null) {
throw new MyTestException();
}
return value.length();
}
private static class MyTestException extends Exception { }
}
ラムダ内のClass.forNameとClass.newInstanceでこの問題が発生したため、次のようにしました。
public Object uncheckedNewInstanceForName (String name) {
try {
return Class.forName(name).newInstance();
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
ラムダの中で、Class.forName( "myClass")。newInstance()を呼び出す代わりに、uncheckedNewInstanceForName( "myClass")を呼び出しました
関数ラッパーを使用する別の解決策は、すべてがうまくいった場合、成功などの結果のラッパーのインスタンスを返すか、失敗などのインスタンスを返すことです。
明確にするためのコード:
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());
この問題も私を悩ませてきました。これが私がこのプロジェクトを作成した理由です。
それを使用すると、次のことができます。
final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;
JDKで定義されている39のインターフェースの合計には、そのようなThrowing
同等のものがあります。これらはすべて@FunctionalInterface
ストリームで使用されるsです(ベースStream
だけでなくIntStream
、LongStream
およびDoubleStream
)。
そして、それぞれが非スロー対応を拡張するので、ラムダで直接使用することもできます。
myStringStream.map(f) // <-- works
デフォルトの動作では、スローするラムダがチェック例外をThrownByLambdaException
スローすると、チェック例外を原因としてがスローされます。したがって、それをキャプチャして原因を取得できます。
他の機能も利用できます。
@FunctionalInterface public interface SupplierWithCE<T, X extends Exception> { T get() throws X; }
-この方法は、ユーザーがキャッチする必要はありませんThrowable
が、特定のではなく、例外をチェックします。
ThrownByLambdaException
するだけで、元の例外が原因になります(またはを使用できますrethrow(...).as(MyRuntimeException.class)
)
Throwing.runnable()
、他の人も使用できるようになりました。常に連鎖機能があります
すでに多くの素晴らしい回答がここに投稿されています。別の視点で問題を解決しようとするだけです。その2セントだけです。どこか間違っている場合は訂正してください。
FunctionalInterfaceのスロー句はお勧めできません
次の理由により、これはスローIOExceptionを強制するのにはおそらく良い考えではないと思います
これは、Stream / Lambdaのアンチパターンのように見えます。全体のアイデアは、提供するコードと例外の処理方法を呼び出し元が決定することです。多くのシナリオでは、IOExceptionはクライアントに適用できない場合があります。たとえば、クライアントが実際のI / Oを実行する代わりにキャッシュ/メモリから値を取得している場合。
また、ストリームでの例外処理は本当に恐ろしいものになります。たとえば、APIを使用すると、コードは次のようになります
acceptMyMethod(s -> {
try {
Integer i = doSomeOperation(s);
return i;
} catch (IOException e) {
// try catch block because of throws clause
// in functional method, even though doSomeOperation
// might not be throwing any exception at all.
e.printStackTrace();
}
return null;
});
醜いですね。さらに、最初のポイントで述べたように、doSomeOperationメソッドは(クライアント/呼び出し元の実装に応じて)IOExceptionをスローする場合とスローしない場合がありますが、FunctionalInterfaceメソッドのthrows句のため、常にトライキャッチ。
このAPIがIOExceptionをスローすることが本当にわかっている場合はどうすればよいですか
次に、おそらく、FunctionalInterfaceを一般的なインターフェイスと混同しています。このAPIがIOExceptionをスローすることがわかっている場合は、おそらくデフォルト/抽象動作も知っています。次のようにインターフェイスを定義し、ライブラリを(デフォルト/抽象実装で)デプロイする必要があると思います
public interface MyAmazingAPI {
Integer myMethod(String s) throws IOException;
}
しかし、クライアントにはtry-catchの問題がまだ残っています。ストリームでAPIを使用する場合でも、恐ろしいtry-catchブロックでIOExceptionを処理する必要があります。
次のように、デフォルトのストリームフレンドリーAPIを提供します。
public interface MyAmazingAPI {
Integer myMethod(String s) throws IOException;
default Optional<Integer> myMethod(String s, Consumer<? super Exception> exceptionConsumer) {
try {
return Optional.ofNullable(this.myMethod(s));
} catch (Exception e) {
if (exceptionConsumer != null) {
exceptionConsumer.accept(e);
} else {
e.printStackTrace();
}
}
return Optional.empty();
}
}
デフォルトのメソッドは、コンシューマオブジェクトを引数として取り、例外を処理します。クライアントの観点から見ると、コードは次のようになります
strStream.map(str -> amazingAPIs.myMethod(str, Exception::printStackTrace))
.filter(Optional::isPresent)
.map(Optional::get).collect(toList());
いいですね もちろん、Exception :: printStackTraceの代わりにロガーやその他の処理ロジックを使用することもできます。
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#exceptionally-java.util.function.Function-と同様のメソッドを公開することもでき ます。以前のメソッド呼び出しからの例外を含む別のメソッドを公開できることを意味します。欠点は、APIをステートフルにすることです。つまり、スレッドセーフを処理する必要があり、最終的にはパフォーマンスヒットになります。ただし、考慮すべきオプションです。
Stream
発生した例外のどの要素を認識するのかわからないので、同意しない。したがって、私は例外ハンドラーを持ち、無効な結果をフィルターに掛けるという考えが気に入っています。MyAmazingAPIは実質的にaであることに注意してくださいFunctionalInterface
(したがって、@ FunctionalInterface アノテーションを追加できます)。また、を使用する代わりに、デフォルト値を使用することもできますOptional.empty()
。
卑劣なスローイディオムはCheckedException
、ラムダ式のバイパスを可能にします。CheckedException
でのaのラップは、RuntimeException
厳密なエラー処理には適していません。
これはConsumer
、Javaコレクションで使用される関数として使用できます。
ここにジブの答えのシンプルで改良されたバージョンがあります。
import static Throwing.rethrow;
@Test
public void testRethrow() {
thrown.expect(IOException.class);
thrown.expectMessage("i=3");
Arrays.asList(1, 2, 3).forEach(rethrow(e -> {
int i = e.intValue();
if (i == 3) {
throw new IOException("i=" + i);
}
}));
}
これは、ラムダを再スローでラップするだけです。それはあなたのラムダに投げられたものをCheckedException
再Exception
投げます。
public final class Throwing {
private Throwing() {}
@Nonnull
public static <T> Consumer<T> rethrow(@Nonnull final ThrowingConsumer<T> consumer) {
return consumer;
}
/**
* The compiler sees the signature with the throws T inferred to a RuntimeException type, so it
* allows the unchecked exception to propagate.
*
* http://www.baeldung.com/java-sneaky-throws
*/
@SuppressWarnings("unchecked")
@Nonnull
public static <E extends Throwable> void sneakyThrow(@Nonnull Throwable ex) throws E {
throw (E) ex;
}
}
これにはETを使用できます。ETは、例外の変換/変換用の小さなJava 8ライブラリです。
ETでは次のようになります。
// Do this once
ExceptionTranslator et = ET.newConfiguration().done();
...
// if your method returns something
Function<String, Integer> f = (t) -> et.withReturningTranslation(() -> myMethod(t));
// if your method returns nothing
Consumer<String> c = (t) -> et.withTranslation(() -> myMethod(t));
ExceptionTranslator
インスタンスはスレッドセーフであり、複数のコンポーネントで共有できます。FooCheckedException -> BarRuntimeException
必要に応じて、より具体的な例外変換ルール(など)を構成できます。他に使用可能なルールがない場合、チェックされた例外は自動的にに変換されRuntimeException
ます。
(免責事項:私はETの作成者です)
私がやっていることは、例外の場合にユーザーが実際に必要な値を提供できるようにすることです。だから私はこのようなものを持っています
public static <T, R> Function<? super T, ? extends R> defaultIfThrows(FunctionThatThrows<? super T, ? extends R> delegate, R defaultValue) {
return x -> {
try {
return delegate.apply(x);
} catch (Throwable throwable) {
return defaultValue;
}
};
}
@FunctionalInterface
public interface FunctionThatThrows<T, R> {
R apply(T t) throws Throwable;
}
そして、これは次のように呼び出すことができます:
defaultIfThrows(child -> child.getID(), null)
私が提供しているライブラリである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");
デフォルトでは、Java 8 関数は例外をスローすることを許可していません。複数の回答で提案されているように、それを達成するための多くの方法があります。1つの方法は次のとおりです。
@FunctionalInterface
public interface FunctionWithException<T, R, E extends Exception> {
R apply(T t) throws E;
}
次として定義:
private FunctionWithException<String, Integer, IOException> myMethod = (str) -> {
if ("abc".equals(str)) {
throw new IOException();
}
return 1;
};
そして、追加しthrows
たりtry/catch
、呼び出し元のメソッドで同じ例外。
チェックされた例外を伝播するカスタムの戻り値の型を作成します。これは、機能インターフェースのメソッドの「例外をスローする」をわずかに変更して、既存の機能インターフェースをミラーリングする新しいインターフェースを作成する代わりになります。
public static interface CheckedValueSupplier<V> {
public V get () throws Exception;
}
public class CheckedValue<V> {
private final V v;
private final Optional<Exception> opt;
public Value (V v) {
this.v = v;
}
public Value (Exception e) {
this.opt = Optional.of(e);
}
public V get () throws Exception {
if (opt.isPresent()) {
throw opt.get();
}
return v;
}
public Optional<Exception> getException () {
return opt;
}
public static <T> CheckedValue<T> returns (T t) {
return new CheckedValue<T>(t);
}
public static <T> CheckedValue<T> rethrows (Exception e) {
return new CheckedValue<T>(e);
}
public static <V> CheckedValue<V> from (CheckedValueSupplier<V> sup) {
try {
return CheckedValue.returns(sup.get());
} catch (Exception e) {
return Result.rethrows(e);
}
}
public static <V> CheckedValue<V> escalates (CheckedValueSupplier<V> sup) {
try {
return CheckedValue.returns(sup.get());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
// Don't use this pattern with FileReader, it's meant to be an
// example. FileReader is a Closeable resource and as such should
// be managed in a try-with-resources block or in another safe
// manner that will make sure it is closed properly.
// This will not compile as the FileReader constructor throws
// an IOException.
Function<String, FileReader> sToFr =
(fn) -> new FileReader(Paths.get(fn).toFile());
// Alternative, this will compile.
Function<String, CheckedValue<FileReader>> sToFr = (fn) -> {
return CheckedValue.from (
() -> new FileReader(Paths.get("/home/" + f).toFile()));
};
// Single record usage
// The call to get() will propagate the checked exception if it exists.
FileReader readMe = pToFr.apply("/home/README").get();
// List of records usage
List<String> paths = ...; //a list of paths to files
Collection<CheckedValue<FileReader>> frs =
paths.stream().map(pToFr).collect(Collectors.toList());
// Find out if creation of a file reader failed.
boolean anyErrors = frs.stream()
.filter(f -> f.getException().isPresent())
.findAny().isPresent();
チェック例外をスローする単一の機能インターフェースが作成されます(CheckedValueSupplier
)。これは、チェックされた例外を許可する唯一の機能的なインターフェイスになります。他のすべての機能インターフェイスはCheckedValueSupplier
、チェックされた例外をスローするコードをラップするために利用します。
CheckedValue
クラスは、チェック例外をスロー任意のロジックを実行した結果を保持します。これにより、コードがのインスタンスにCheckedValue
含まれる値にアクセスしようとする時点まで、チェックされた例外の伝播が防止されます。
CheckedValue#get()
が呼び出されるまで例外が発生したことを認識していません。一部の機能インターフェース(Consumer
例えば)は、戻り値を提供しないため、別の方法で処理する必要があります。
1つのアプローチは、ストリームを処理するときに適用される、コンシューマーの代わりに関数を使用することです。
List<String> lst = Lists.newArrayList();
// won't compile
lst.stream().forEach(e -> throwyMethod(e));
// compiles
lst.stream()
.map(e -> CheckedValueSupplier.from(
() -> {throwyMethod(e); return e;}))
.filter(v -> v.getException().isPresent()); //this example may not actually run due to lazy stream behavior
または、いつでもにエスカレーションできますRuntimeException
。内からのチェック済み例外のエスカレーションをカバーする他の回答がありますConsumer
。
機能的なインターフェイスをすべて避けて、古き良きforループを使用してください。
unchecked()
複数のユースケースを処理するという、多重定義されたユーティリティ関数を使用しています。
いくつかの使用例
unchecked(() -> new File("hello.txt").createNewFile());
boolean fileWasCreated = unchecked(() -> new File("hello.txt").createNewFile());
myFiles.forEach(unchecked(file -> new File(file.path).createNewFile()));
支援ユーティリティ
public class UncheckedUtils {
@FunctionalInterface
public interface ThrowingConsumer<T> {
void accept(T t) throws Exception;
}
@FunctionalInterface
public interface ThrowingSupplier<T> {
T get() throws Exception;
}
@FunctionalInterface
public interface ThrowingRunnable {
void run() throws Exception;
}
public static <T> Consumer<T> unchecked(
ThrowingConsumer<T> throwingConsumer
) {
return i -> {
try {
throwingConsumer.accept(i);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
};
}
public static <T> T unchecked(
ThrowingSupplier<T> throwingSupplier
) {
try {
return throwingSupplier.get();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static void unchecked(
ThrowingRunnable throwing
) {
try {
throwing.run();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
提供されているソリューションのいくつかは、Eの汎用引数を使用して、スローされる例外のタイプを渡します。
さらに一歩進んで、例外のタイプを渡すのではなく、次のように例外のタイプのコンシューマを渡します...
Consumer<E extends Exception>
Consumer<Exception>
アプリケーションの一般的な例外処理のニーズをカバーする、再利用可能なバリエーションをいくつか作成する場合があります。
私は一般的なことをします:
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());
使用Jool Library
またはが言うjOOλ library
からJOOQ
。これは、チェックされていない例外処理インターフェイスを提供するだけでなく、Seqクラスに多くの便利なメソッドを提供します。
また、最大16個のパラメーターを持つ機能インターフェースも含まれています。また、さまざまなシナリオで使用されるタプルクラスを提供します。
具体的には、org.jooq.lambda.fi.util.function
パッケージのライブラリ検索で。Checkedが先頭に追加されたJava-8のすべてのインターフェースが含まれています。参考のために以下を参照してください:-
私は、それらをキャッチしたり、ラップしたりする必要なしにRuntimeException
Java例外をどこにでも投げる一般的な魔法を備えた小さなlibの作者です。
使用法:
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);
}
}
}
public void frankTest() {
int pageId= -1;
List<Book> users= null;
try {
//Does Not Compile: Object page=DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> new Portal(rw.getInt("id"), "", users.parallelStream().filter(uu -> uu.getVbid() == rw.getString("user_id")).findFirst().get(), rw.getString("name")));
//Compiles:
Object page= DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> {
try {
final Book bk= users.stream().filter(bp -> {
String name= null;
try {
name = rw.getString("name");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bp.getTitle().equals(name);
}).limit(1).collect(Collectors.toList()).get(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new Portal(rw.getInt("id"), "", users.get(0), rw.getString("name"));
} );
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
<code>/<code>
::)の代わりに4スペースを使用してプレゼンテーションを修正できます