【问题标题】:Can implementations of Handler.publish() throw runtime exceptions?Handler.publish() 的实现可以抛出运行时异常吗?
【发布时间】:2016-05-31 07:18:31
【问题描述】:

我有一个关于 java.util.logging.Handler 的问题:

这个抽象方法的实现是否允许抛出 RuntimeExceptions,还是应该总是向错误管理器报告?

文档没有具体说明,但是类中的其他方法明确说明了它们可以抛出什么:

public abstract void publish(LogRecord record) 发布一个 LogRecord。 日志记录请求最初是向 Logger 对象发出的,该对象 初始化LogRecord并转发到这里。

Handler 负责格式化消息,何时以及是否 必要的。格式应包括本地化。

参数:record - 日志事件的描述。空记录是 默默地忽略并且不发布

[链接:https://docs.oracle.com/javase/7/docs/api/java/util/logging/Handler.html#publish(java.util.logging.LogRecord)]

【问题讨论】:

    标签: java java.util.logging


    【解决方案1】:

    这是一种 API 规范并不总是与实现匹配的情况。源代码中的不成文规则似乎是:

    1. 空记录的处理可能是恶意的或被忽略的。 StreamHandler ignore nullMemoryHandler is null hostile 的子类。记录器从不传递 null 来发布,因此您选择什么并不重要。
    2. isLoggable 抛出的任何运行时异常都会逃逸处理程序。这意味着过滤器抛出的任何异常都会转义发布方法,并且不会被错误管理器捕获。请注意没有枚举 ErrorManager.FILTER_FAILURE,这意味着该行为是故意的。
    3. ErrorManager 文档中列举了发布不应引发的异常。大多数情况是格式和书写错误。

    真正的发布应该委托给错误管理器来确定是否publish throws exceptions or not。来自Handler.setErrorManager 文档:

    如果在使用此 Handler 时发生任何错误,将调用 ErrorManager 的 "error" 方法。

    这意味着发布应该遵循默认情况下不会抛出的错误管理器的行为。

    如果你想通过 Handler.reportError 获取异常,你必须使用偷偷摸摸的 throw。

    public class HostileErrorManager extends ErrorManager {
    
        @Override
        public void error(String msg, Exception ex, int code) {
            sneakyThrow(new Throwable(msg + ": " + code, ex));
        }
    
        @SuppressWarnings("unchecked")
        private <T extends RuntimeException> void sneakyThrow(Throwable t) throws T {
            throw (T) t;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-28
      • 2012-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-03
      • 2015-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多