记录未经检查的异常

3

我正在阅读J. Bloch的《Effective Java》,现在我正在阅读关于文档化未检查异常的部分。他说:

使用Javadoc @throws标签记录方法可能抛出的每个未检查异常[...]。

public interface Parameters {
    //other method ommited

    /**
     * __DESCRIPTION_OMMITED__
     *
     * @throws ParameterAlreadyExistsException  If a parameter with the same name already exists in this container.
     */
    public <M> void put(ParameterMetaData<M> p, M value);
}

public interface ParameterMetaData<ValueType>{ }仅仅是一个标记,用于确保编译时类型安全。ParameterAlreadyExistsExceptionRuntimeException的直接子类。

这是它的基本实现:

public final class ParametersImpl implements Parameters{

    private final Map<ParameterMetaData<?>, Object> parameters;

    @Override
    public <M> void put(ParameterMetaData<M> p, M value){
        if(value == null)
            return;
        if(parameters.containsKey(p))
            throw new ParamAlreadyExistsException(String.format("The parameter with the name %s already exists. Value: %s", p.getClass(), parameters.get(p)));
        try{
            parameters.put(p, value);
        } catch (Exception e){
            throw new RuntimeException(String.format("Parameter insertion failed. ParameterMetaData: %s Value: %s", p.getName(), value), e);
                         // ^----------------Here non-documented exception is thrown.
        }
    }

    //remainders ommited
}

由于Map#put(K, V)方法会抛出异常,而我的实现使用它并在出现问题时抛出RuntimeException,我应该如何记录这个事实?我是否应该这样做?目前,仅凭接口文档很难说出为什么会抛出RuntimeException。

问题:我应该如何处理与实现相关的异常?我应该记录它们吗?


1
Map.put() 不会抛出任何已检查异常。它抛出的所有运行时异常都是代码中错误的信号。您不应该捕获它们中的任何一个。 - JB Nizet
相关链接:https://dev59.com/vXRA5IYBdhLWcg3wyRJ7?rq=1 - user180100
@JBNizet 实际上并不会。但如果我不捕获它,它将传播并且接口的客户端会看到一些关于放入内部HashMap的混乱消息。也许捕获它并将其转换为更合适的异常会更好? - St.Antario
1
这不应该发生,因为这是一个错误,你应该在没有错误的情况下进行测试和发布。当然会发生错误,因为没有人是完美的。但是,有一个指向错误的异常是一件好事:你可以快速确定它来自哪里并修复它。保持你的代码整洁。你不能合理地将每个方法调用都包装在try-catch块中,以防该方法调用抛出意外的运行时异常。 - JB Nizet
1个回答

3
我该如何处理实现特定的异常?我需要记录它们吗?
不需要。像JB Nizet在评论中所指出的那样,这是一个bug,你应该测试/修复这些问题。
如果你担心会向用户显示内部错误,可以显示一个通用错误,例如“发生未知错误”。在日志记录中,你可以记录实际的异常,以便用户向你报告错误,并查看出了什么问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接