处理侦听器抛出的java异常

dom*_*ino 4 java exception-handling

假设您正在为异步运行的对象编写库.要通知调用者异步对象的状态,调用者必须实现侦听器接口.

现在,当使用侦听器时,侦听器可能会做错,这将导致在库对象中抛出异常.

public interface SomeListener {
    public void progressNotification(int status);
}

public class SomeClass {
    SomeListener listener = null;
    …
    public void setListener(SomeListener listener) {
        this.listener = listener;
    }
    …
    public void someRandomMethod() {

        int progressStatus = 0;
        //Do some stuff here that updates progressStatus

        //then notify the caller
        if (listener != null) {
            listener.progressNotification(progressStatus);
        } 
    }
}

public class CallerClass implements SomeListener{
    public void progressNotification(int status) {
        //do something that will throw an exception 
        //e.g assume status is 0
        int x = 200/status; //this will throw an ArithmeticException because of division by zero
    }
}
Run Code Online (Sandbox Code Playgroud)

如果SomeClass没有捕获异常并处理它,这将导致之后的任何代码listener.progressNotification(progressStatus);不被执行而使对象处于"不正确"状态.

所以我的问题是,在库中处理这种异常的最佳方法是什么?

我见过一个这样做的库:

    if (listener != null) {
        try {
            listener.progressNotification(progressStatus);
        }catch (Thrwowable th) {
            System.err.println("An uncaught throwable " + th);
        }
    } 
Run Code Online (Sandbox Code Playgroud)

这对我来说不合适.

JB *_*zet 7

对我来说,听众的合同应该明确界定:

  • 它必须快速返回(即不暂停或睡眠线程等),
  • 它不能抛出任何运行时异常.

如果它确实抛出运行时异常,那么监听器就会破坏API契约,因此它是API的客户端代码的错误,而不是API本身的错误.

除了明确定义和记录合同以及解释违约的潜在影响(即不确定状态,无论如何)之外,我不会做任何其他事情.如果客户端真的想要保护自己免受编程错误的影响,他仍然可以将所有侦听器代码包装在try/catch中,如您的示例所示.