【问题标题】:Replace a checked exception with a runtime exception?用运行时异常替换检查异常?
【发布时间】:2012-06-08 06:47:07
【问题描述】:

鉴于我基本上想消除检查异常的使用并将它们转换为运行时异常,我通常会这样做:

try {
    file.read();
} catch (IOException e){
    throw new RuntimeException(e); 
}

这样做有几个缺点,但最让我恼火的是我的运行时异常会包含嵌套的堆栈跟踪。基本上我想用原始消息和堆栈跟踪重新抛出“IOException”作为 RuntimeException(或“IORuntimeException”),这样我就可以避免无用的嵌套堆栈跟踪。我在中间某处重新抛出异常的“事实”对我来说似乎只是无用的噪音。

这可能吗?有没有这样做的图书馆?

【问题讨论】:

  • this 有用吗?
  • 如果你对嵌套的堆栈跟踪感到恼火,你会讨厌大多数倾向于广泛使用它们的框架和库。如果我是你,我会习惯的。
  • @KazekageGaara,很好。如果您将其发布为答案,我会赞成。
  • @artbristol 我知道,但我可以尽自己的一份力量来尽量减少问题并避免 400 行堆栈跟踪。

标签: java exception-handling


【解决方案1】:

Project Lombok 允许您完全禁用检查异常。

【讨论】:

  • 很公平,但这对我来说太过分了。我宁愿自己在某个地方做
  • 我怀疑您要解决的问题是否有非 hacky 解决方案。
【解决方案2】:

跟进我的评论。这是一个article,必须对这个问题有所了解。它使用sun.misc.Unsafe 重新抛出异常而不包装它们。

【讨论】:

    【解决方案3】:
    class IORuntimeException extends RuntimeException {
    
        final IOException ioex;
    
        public IORuntimeException(IOException ioex) {
            this.ioex = ioex;
        }
    
        @Override
        public String getMessage() {
            return ioex.getMessage();
        }
    
        @Override
        public StackTraceElement[] getStackTrace() {
            return ioex.getStackTrace();
        }
    
        //@Override
        // ...
    }
    

    (完整类可用here,由 Eclipse“生成委托方法”宏生成。)

    用法:

    try {
        ...
    } catch (IOException ioex) {
        throw new IORuntimeException(ioex);
    }
    

    【讨论】:

    • 这种方法的问题是它不能泛化到任何Exception类型,从而导致过多的样板和代码重复。
    • 是的,但是类型信息丢失了。只有当 Java 已经具体化了泛型......然后我们才能用泛型做到这一点。
    • 这个响应的一个有趣的方面是它并没有真正起作用;) "fillInStackTrace" 是从 throwable 构造函数中调用的,这意味着子类中的成员变量尚未初始化。
    • 啊,那么删除@Override ... fillInStackTrace 呢?
    【解决方案4】:

    如果您正在考虑使用其他答案的 Unsafe(我不建议,但无论如何),另一种选择是滥用泛型以使用这对邪恶的方法引发检查异常(来自 http://james-iry.blogspot.co.uk/2010/08/on-removing-java-checked-exceptions-by.html):

       @SuppressWarnings("unchecked")
       private static <T extends Throwable, A> 
         A pervertException(Throwable x) throws T {
          throw (T) x;
       }
    
    
       public static <A> A chuck(Throwable t) {
          return Unchecked.
            <RuntimeException, A>pervertException(t);
       }
    

    您也可以查看 com.google.common.base.Throwables.getRootCause(Throwable) 并打印其(根)堆栈跟踪。

    【讨论】:

      【解决方案5】:

      听起来你实际上需要检查异常

      【讨论】:

        【解决方案6】:

        从 Java 8 开始,还有另一种方式:

        try {
          // some code that can throw both checked and runtime exception
        } catch (Exception e) {
          throw rethrow(e);
        }
        
        @SuppressWarnings("unchecked")
        public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T {
            throw (T) throwable; // rely on vacuous cast
        }
        

        * 更多信息here.

        【讨论】:

          猜你喜欢
          • 2023-04-08
          • 2019-06-24
          • 1970-01-01
          • 2012-07-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-09
          • 2011-03-10
          相关资源
          最近更新 更多