19

有时,我最终不得不捕获一个我知道永远不会发生的异常,例如这里

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. 有没有更好的办法?

4

5 回答 5

9

我抓住Exception并将它包裹在一个Error. 来自以下文档Error

Error 是 Throwable 的子类,表示合理的应用程序不应尝试捕获的严重问题。

于 2012-07-02T08:39:23.053 回答
6

我会跳过有趣的消息。

顺便说一句:我有一个案例,其中一段代码(在一个小型库中)只是假设编码可用。只有它被部署在有限的设备上并在运行时爆炸。

已检查的异常用于显示我们代码中应该暂停一秒钟的位置并考虑较少经过的路径(如“当网络死亡时我的应用程序会做什么”和其他极端情况)。将它们包装在 IllegalStateException 中并重新抛出是一种已签署的合同,程序员在其中说:“是的,考虑到所有风险,我对这里的现场承担全部责任”。如果不是检查异常,我们将无法从明显缺乏思考中知道一个有意识的决定。

于 2012-07-02T08:42:24.193 回答
3

好吧,恕我直言,有一个比“记录[ging]关于宇宙法则如何变化的有趣错误”更好的方法,因为这样做你是“很可爱”,这在朋友中很好,但不是普遍的(没有双关语预期)接受。你的代码可能会被其他人阅读,如果你的幽默(对他们)平淡无奇,你还没有真正交到任何朋友。

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

如果你想超级有野心,你可以写一个注解,比如Lombok 中的 SneakyThrows。您是否会认为这“更好”只是一个品味问题。:)

请注意,此问题已在https://softwareengineering.stackexchange.com/questions/122233/how-to-deal-with-checked-exceptions-that-c​​annot-ever-be- throw 上进行了讨论。

于 2012-07-02T08:31:16.583 回答
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 RuntimeException还是一个ImpossibleError extends Error

于 2016-04-20T07:10:04.637 回答
0

如果您在项目中使用Lombok,您可以注释周围的方法,使用@SneakyThrows哪种隐藏检查的异常RuntimeException(因此无需在子句中包围try-catch或声明它)。throws

例如:

@SneakyThrows(URISyntaxException.class)
public void methodWithURL(URL url){ // No throws here
    URI uri = new URI(url); // Assume no invalud URI syntax possible
}
于 2021-01-15T20:58:50.220 回答