你如何处理Java中的“不可能”异常?

时间:2012-07-02 08:14:27

标签: java exception-handling

有时候,我最终还是要抓住一个我知道永远不会发生的例外,比如这里

URLDecoder.decode("some string", "UTF-8"); //No unknown encoding possible

或在这里:

public void methodWithURL(URL url){
    URI uri = new URI(url); //No invalud URI syntax possible
}

你怎么处理这个?我通常会记录一个关于宇宙定律如何变化的有趣错误,然后抛出一个RuntimeException。还有更好的方法吗?

5 个答案:

答案 0 :(得分:9)

我抓住Exception并将其包裹在Error中。来自Error的文件:

  

错误是Throwable的子类,表示严重问题   合理的申请不应该试图抓住。

答案 1 :(得分:5)

我会跳过有趣的信息。

BTW:我遇到过一段代码(在一个小型库中)假设编码可用的情况。只有它部署在有限的设备上并在运行时爆炸。

已检查的异常用于在我们的代码中显示我们应暂停一秒的位置并考虑路径较少的路径(如“我的应用程序在网络死机时所执行的操作”和其他极端情况)。将它们包装在IllegalStateException并重新抛出是一种签署的合同,程序员说:“是的,所有风险都被视为我对此处的现场承担全部责任”。如果它不是用于检查例外情况,那么我们就无法从明显的缺乏思想中了解一个有意义的决定。

答案 2 :(得分:3)

嗯,恕我直言 比“记录宇宙的规律如何变化的有趣错误”更好的方式,因为这样做是“可爱”,其中朋友很好,但并不普遍(没有双关语意)接受。你的代码可能会被其他人阅读,如果你的幽默不平衡(在他们身上)你还没有真正交到任何朋友。

许多风格指南为不可能的例外提出建议。您可以使用空catch块,并将exception参数命名为willNeverHappen;你可以在空块中发表评论;你可以抛出一个运行时异常(可能是最好的,因为你可能拼写错误的UTF-8!)

如果你想超级雄心勃勃,你可以写一个注释,比如SneakyThrows in Lombok。你是否会认为这种“更好”只是一种品味问题。 :)

请注意,此问题已在https://softwareengineering.stackexchange.com/questions/122233/how-to-deal-with-checked-exceptions-that-cannot-ever-be-thrown上讨论过。

答案 3 :(得分:0)

这是我的解决方案 - 为Android开发,但可以很容易地适应“常规”Java:

public class ImpossibleException extends RuntimeException {
    public ImpossibleException(@NonNull String whyNotPossible) {
        this(whyNotPossible, null);
    }

    public ImpossibleException(@NonNull String whyNotPossible, Throwable throwable) {
        super("Impossible exception: " + whyNotPossible, throwable);
        Log.e("Impossible", whyNotPossible, throwable);
    }
}

用法:

try {
    byte[] data = "Hello".getBytes("utf-8");
    Log.i("Test", "data.length=" + data.length);
} catch (UnsupportedEncodingException e) {
    throw new ImpossibleException("Android always supports utf-8", e);
}

whyNotPossible构造函数意味着无需在出现错误的地方记录错误,也无需发表评论。

我想如果这应该是ImpossibleException extends RuntimeExceptionImpossibleError extends Error,那就是品味问题。

答案 4 :(得分:0)

如果你在项目中使用了 Lombok,你可以用 @SneakyThrows 注释周围的方法,在 RuntimeException 中隐藏检查异常的类型(因此不需要用 {{1} } 也不在 try-catch 子句中声明)。

例如:

throws