首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可选异常捕获

可选异常捕获
EN

Stack Overflow用户
提问于 2013-08-08 17:15:23
回答 4查看 2K关注 0票数 0

是否有可能做出一个可选的异常被捕获?

换言之,一种例外情况可以:

  • 被捕捉到在一个尝试-捕捉块中
  • 或者跳过,如果它不存在尝试-捕捉块。

为了可视化,我有一个ReportedException,它只是RuntimeException的一个普通子类,希望能够在需要时捕获它:

代码语言:javascript
复制
try
{
    hideWindow();
}
catch (ReportedException ex)
{
    // Window could not be hidden.
    // Exception has already been caught and logged by parseInput(),
    // and now we're going to do something more.

    printAdditionalErrorMessage();
}

注:我编辑了上面的例子,以更好地适应我的问题。

如果结果与此无关,则跳过捕捉:

代码语言:javascript
复制
hideWindow(); // We don't care if there was an error or not.
openAnotherWindow();

我知道我可以将catch块保留为空,并且具有与上面相同的内容,但是我经常使用ReportedException,这会使我的代码高度不可读。

如果这是不可能的(我想是的),你会推荐什么替代/步行?

示例中使用的方法名仅为foo和bar的。

编辑:,我知道我不需要抓住RuntimeExceptions。我想要的是,如果它们发生了,就忽略它们。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-08-08 18:21:53

我对如何使用ThreadLocal有点模糊(而且还有其他一些教程),但如下所示:

代码语言:javascript
复制
public class IgnorableException {  

     static class DontIgnoreCount  {
         int count;
     }

     // Thread local variable containing each thread's ID
     private static final ThreadLocal<DontIgnoreCount> dontIgnoreCount =
         new ThreadLocal<DontIgnoreCount>();

     static void incrementDontIgnore() {
         DontIgnoreCount counter = dontIgnoreCount.get();
         if (counter == null) {
             counter = new DontIgnoreCount();
             dontIgnoreCount.set(counter);
         }
         counter.count++;
     }

     static void decrementDontIgnore() {
         DontIgnoreCount counter = dontIgnoreCount.get();
         // Must not be null here
         counter.count--;

     static bool shouldSignal() {
         DontIgnoreCount counter = dontIgnoreCount.get();
         return counter.count > 0;
     }
}

若要使用,请在尝试范围的早期调用DontIgnoreCount.incrementIgnoreCount(),在最终范围内调用DontIgnoreCount.decrementIgnoreCount()。

当对遵循此协议的异常发出信号时,只有当shouldSignal返回true时才发出信号。

代码语言:javascript
复制
void iWannaCatchException() {
    try {
        IgnornableException.incrementDontIgnore();
        int x = someOptionallySignallingMethod();
    }
    catch (...) {
        ...
    }
    finally {
        IgnorableException.decrementDontIgnore();
    }
}

void iDontWannaCatchException() {
    int x = someOptionallySignallingMethod();
}

int someOptionallySignallingMethod() {
    if (somethingBad) {
        if (IgnorableException.shouldSignal()) {
            throw new BadException();
        }
    }
    return 42;
}

请注意,上面没有显示的是您必须添加的任何throws子句,以使编译器保持高兴。这一机制不会消除对这些问题的需要。

您还可以使用委托/观察者方案,将简单的计数器替换为一堆观察者对象,并将一条消息传递给观察者和抛出异常。但是,这本身(没有耦合的异常/尝试范围)将不允许将堆栈吹走到适当的恢复点。

票数 2
EN

Stack Overflow用户

发布于 2013-08-08 17:23:04

例外情况应用于例外情况。

从您的示例来看,如果未隐藏的窗口是典型事件,则不应抛出异常。如果这是您的函数,那么使用一个返回值来指示它是否成功,而不是抛出异常。然后,当您不关心返回值是否成功时,就可以安全地忽略它。

如果没有对该方法的控制,则可以将其包装在另一个捕获异常并将其转换为返回值的方法中。例如。

代码语言:javascript
复制
private boolean tryHideWindow() {
    try {
        hideWindow();
    }
    catch (ReportedException ex) {
        return false;
    }
    return true;
}

如果需要一些异常参数来确定要执行什么操作,则可以返回异常。

代码语言:javascript
复制
private static class MyReturnType {
    private final Throwable thrown;
    private final OrigRtnType returnVal;
    public MyReturnType(Throwable thrown) {
        this.thrown = thrown;
        this.returnVal = null;
    }
    public MyReturnType(OrigRtnType returnVal) {
        this.thrown = null;
        this.returnVal = returnVal
    }
    public boolean wasExceptionThrown() {
        return thrown != null;
    }
}

private MyReturnType tryHideWindow() {
    try {
        OrigRtnType returnVal = hideWindow();
    }
    catch (ReportedException ex) {
        return new MyReturnType(ex);
    }
    return new MyReturnType(returnVal);
}

这是你问题的答案,但这不一定是个好主意。正如其他人会不假思索地评论,对程序流使用异常并不理想。

票数 3
EN

Stack Overflow用户

发布于 2013-08-08 17:19:58

听起来,您想要使用异常来控制流,而不是报告真正的例外情况。

对流控制使用异常通常是不允许的。常见的方法是将成功/失败指示作为函数的返回值返回。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18132055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档