【发布时间】:2021-10-31 07:47:18
【问题描述】:
在函数的情况下,当异常可能只在它们的执行位置抛出(基于我缺乏知识,这对我来说目前还不确定),有时罪魁祸首可能取决于创建 lambda 的方式,例如:
// merge() will throw an exception if Function<S, Observable<T>> switchMap returns null.
public<S> void mergeSwitch(Observable<S> source, Function<S, Observable<T>> switchMap) {
final Mergeable<T> res = new Mergeable<>();
final Consumer<T> observer = creator(res, this); // Secondary subscription
setSource(
source, // Main subscription
new StateAwareObserver<S>() { // >>> implements Consumer<S>
Observable<T> switchRes = new Observable<>(); // Mediator
@Override
protected void onAdded() {
res.add(observer);
}
@Override
protected void onRemoved() {
res.remove(observer);
}
@Override
public void accept(S s) {
Observable<T> switchS = switchMap.apply(s);
if (switchRes != switchS) {
switchRes = switchS;
res.merge(switchS); //Where merge() throws if switchMap returns null
}
}
}
);
}
}
我尝试从 accept() 方法重新抛出异常,但它永远不会被推送(拉出?)超出其消费点(消费者接受“s”的地方):
for (int i = observers.size() - 1; i >=0 ; i--) {
observers.get(i).accept(processed); // << -- StateAwareObserver<S> is stored in the *list*
}
-在这种情况下,我使用“超越”一词,但我需要在构造点抛出异常。-
实际上真正的罪魁祸首可能是方法的执行:mergeSwitch(Observable<S> source, Function<S, Observable<T>> switchMap)
它创建了消费者,可能遗漏了一些重要的东西。
或者就我而言,执行mergeSwitch()的方法:
public<S> Forkable<S> forkSwitch(Function<T, Observable<S>> switchMap) {
Forkable<S> res = new Forkable<>();
res.mergeSwitch(this, switchMap);
return res;
}
在这种情况下,问题是函数留下了一个空值。
public Holders.Forkable<List<Preset>> ledgerPresets = presetDao.forkSwitch(
presetDao -> ledgerId.forkSwitch(
aLong -> null
)
);
所以如果我们看一下消费者层面,真正的罪魁祸首是:
@Override
public void accept(S s) {
int sVersion = source.getVersion();
if (sVersion != oVersion) {
Observable3<T> switchS = switchMap.apply(s); //< -- HERE
if (switchRes != switchS) {
switchRes = switchS;
res.merge(switchS);
}
oVersion = sVersion;
}
}
在这种特殊情况下,事情很容易失控,因为日志可能不会在最近的消费点停止,但错误可能会一直回到根节点。
事情可能会变得更加复杂,因为作为异常起源的 merge() 方法可能已从 3 种不同的方法中使用。
理想的情况是在此处抛出异常:
public Holders.Forkable<List<Preset>> ledgerPresets = presetDao.forkSwitch(
presetDao -> ledgerId.forkSwitch( // <--- HERE
aLong -> null
)
);
但是我还没有找到一种方法来管理这个特殊的异常重新抛出案例。
【问题讨论】:
标签: java function exception rethrow