[英]Why does Scanner#nextInt inside for loop keep throwing an exception?
[英]Throwing exception inside lambda does not work
我在 lambda 中拋出異常時遇到了一些問題,請考慮以下代碼:
public interface StoreTransactionalExecutable {
void execute(@NotNull final StoreTransaction txn);
}
還有一個經理 class:
public final class DatabaseManager {
// ...
@Override
public void transactPersistentEntityStore(String dir, StoreTransactionalExecutable txn) {
final PersistentEntityStore entityStore =
getPersistentEntityStore(dir, isReadOnly);
entityStore.executeInTransaction(txn);
}
// ...
}
當像下面這樣訪問管理器 class 方法transactPersistentEntityStore
時,它可以工作:
public class Service {
databaseManager.transactPersistentEntityStore("/dbPath", txn -> {
txn.find(); // do stuff (throws and works)
});
}
但是,如果這樣,它會引發編譯時錯誤
public class Service {
databaseManager.transactPersistentEntityStore("/dbPath", rethrow(
transaction -> {
StoreTransaction txn = (StoreTransaction) transaction;
txn.find(); // do stuff
}
));
}
這是扔的東西
[ERROR] method com.myproject.store.DatabaseManager.transactPersistentEntityStore(java.lang.String,jetbrains.exodus.entitystore.StoreTransactionalExecutable) is not applicable
[ERROR] (argument mismatch; no instance(s) of type variable(s) T exist so that java.util.function.Consumer<T> conforms to jetbrains.exodus.entitystore.StoreTransactionalExecutable)
[ERROR] method com.myproject.store.DatabaseManager.<T,B>transactPersistentEntityStore(java.lang.String,java.util.Map<java.lang.Class<T>,B>,jetbrains.exodus.entitystore.StoreTransactionalExecutable) is not applicable
[ERROR] (cannot infer type-variable(s) T,B
[ERROR] (actual and formal argument lists differ in length))
rethrow
和ThrowingConsumer
的代碼是這樣的:
public final class Throwing {
private Throwing() {}
@Nonnull
public static <T> Consumer<T> rethrow(@Nonnull final ThrowingConsumer<T> consumer) {
return consumer;
}
@SuppressWarnings("unchecked")
@Nonnull
public static <E extends Throwable> void sneakyThrow(@Nonnull Throwable ex) throws E {
throw (E) ex;
}
}
和
@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T>{
@Override
default void accept(final T e) {
try {
accept0(e);
} catch (Throwable ex) {
Throwing.sneakyThrow(ex);
}
}
void accept0(T t) throws Throwable;
}
我真的很想知道這里有什么問題? 任何提示將不勝感激。
關於第一個編譯器錯誤:
如果您仔細閱讀錯誤“參數不匹配;不存在類型變量 T 的實例,因此 java.util.function.Consumer 符合 jetbrains.exodus.entitystore.Sto reTransactionalExecutable”
你會注意到一些事情:
execute
方法 not accept
。 所以在entityStore.executeInTransaction(txn);
里面的代碼調用execute
方法而不accept
因此,當您將 Consumer object 傳遞給transactPersistentEntityStore
方法時,編譯器會抱怨。
如果我錯了,請糾正我。
一種“偷偷摸摸”的方式來拋出這個(但有一個try-catch)是做一個:
public class UncheckedException extends RuntimeException {
public UncheckedException(Throwable cause) {
super(cause);
}
}
然后像這樣使用:
class Scratch {
public static void main(String[] args) {
databaseManager.transactPersistentEntityStore("/dbPath", txn -> {
try {
somethingThatThrows();
} catch (Exception e) {
throw new UnchecekdServiceException(e);
}
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.