如何在 Java 6 中捕获所有已检查的异常(在一个块中)?

Posted

技术标签:

【中文标题】如何在 Java 6 中捕获所有已检查的异常(在一个块中)?【英文标题】:How to catch all checked exceptions (in a single block) in Java 6? 【发布时间】:2013-01-24 03:22:07 【问题描述】:

重要提示:此问题仅与 Java 6(及以下)有关。

层次结构here显示JavaExceptions分为两种类型:RuntimeException[不是RuntimeException]

不是更好吗?例如,下面的语句有相当多的检查异常:

try 
    transaction.commit();
 catch (SecurityException e) 
 catch (IllegalStateException e) 
 catch (RollbackException e) 
 catch (HeuristicMixedException e) 
 catch (HeuristicRollbackException e) 
 catch (SystemException e) 

我只对它是成功还是失败真正感兴趣,因此希望将已检查的异常作为一个组来处理,而不是未检查的异常,因为捕获意外错误不是一个好习惯。所以考虑到这一点,也许我可以这样做:

try 
    transaction.commit();
 catch (Exception e) 
    if (e instanceof RuntimeException) 
        // Throw unchecked exception
        throw e;
    
    // Handle checked exception
    // ...

但这似乎非常骇人听闻。有没有更好的办法?

【问题讨论】:

您使用的是哪个版本的 Java? (Java 7 在这方面有额外的特性。) 哦-不知道!我正在使用 1.6。 值得注意的是,Java异常实际上分为三种,不是两种,而是三种RuntimeException、非RuntimeExceptions和Errors的异常。 嗯,不是严格 true,因为错误不是异常。 正确,我没有考虑那种分离,我猜更正确的说法是“Java throwables分为三个部分” 【参考方案1】:

如果我理解正确,那么你就快到了。只需捕获 RuntimeException。这将在层次结构中捕获 RuntimeException 及其下的所有内容。然后是异常的失败,你被覆盖了:

尝试 事务.commit(); 捕捉(运行时异常 e) // 抛出未经检查的异常 扔 e; 捕捉(异常 e) // 处理检查异常 // ...

【讨论】:

喜欢它。我仍然想知道为什么他们没有包含“NonRuntimeException”的类别,但这确实有效。 值得注意的是,这不是 Java 方式(也就是说,它不是非常 Java 来捕获非常普遍的异常类型)。也就是说,我个人认为这很好,并且 java 出错了异常。【参考方案2】:

Java 7 允许你这样的构造:

try 
    transaction.commit();
 catch (SecurityException | IllegalStateException  | RollbackException | HeuristicMixedException  e ) 
   // blablabla

UPD:我认为,在早期版本的 Java 中没有很好且方便的方法来执行此操作。这就是Java 语言的开发人员在Java 7 中引入这种结构的原因。因此,您可以为Java 6 设计自己的方法。

【讨论】:

OP 明确表示他使用的是 1.6 版而不是 1.7 版 可爱,我想知道这样的东西是否存在!很高兴知道他们已经在 7 中改进了它,但不幸的是我被限制在 6 中。虽然我想有点让这个问题变得多余! @BenjaminGruenbaum 他是在我发布我的答案后说的。你认为我应该立即删除我的答案吗? @Andremoniy 不,我认为这是一个很好的答案,可以帮助未来的用户,我发表了这个评论,所以你也希望在其中添加一些关于 java 1.6 案例的内容。此外,这里有一个很好的链接,说明了 1.7 docs.oracle.com/javase/7/docs/technotes/guides/language/… 中添加的功能 我们不能有一个父类来处理所有这些异常【参考方案3】:

我在另一个帖子中给出了类似的答案,所以是的,它是复制过去:

我要做的是有一个静态方法来处理所有异常,并将日志添加到 JOptionPane 以将其显示给用户,但您可以将结果写入 FileWriter 中的文件,并包装在 @987654322 中@。 对于主要的静态方法,要捕获未捕获的异常,我会这样做:

SwingUtilities.invokeLater( new Runnable() 
    @Override
    public void run() 
        //Initializations...
    
);


Thread.setDefaultUncaughtExceptionHandler( 
    new Thread.UncaughtExceptionHandler() 
        @Override
        public void uncaughtException( Thread t, Throwable ex ) 
            handleExceptions( ex, true );
        
    
);

至于方法:

public static void handleExceptions( Throwable ex, boolean shutDown ) 
    JOptionPane.showMessageDialog( null,
        "A CRITICAL ERROR APPENED!\n",
        "SYSTEM FAIL",
        JOptionPane.ERROR_MESSAGE );

    StringBuilder sb = new StringBuilder(ex.toString());
    for (StackTraceElement ste : ex.getStackTrace()) 
        sb.append("\n\tat ").append(ste);
    


    while( (ex = ex.getCause()) != null ) 
        sb.append("\n");
        for (StackTraceElement ste : ex.getStackTrace()) 
            sb.append("\n\tat ").append(ste);
        
    

    String trace = sb.toString();

    JOptionPane.showMessageDialog( null,
        "PLEASE SEND ME THIS ERROR SO THAT I CAN FIX IT. \n\n" + trace,
        "SYSTEM FAIL",
        JOptionPane.ERROR_MESSAGE);

    if( shutDown ) 
        Runtime.getRuntime().exit( 0 );
    

在你的情况下,你可以像我之前告诉你的那样写一个日志,而不是向用户“尖叫”:

String trace = sb.toString();

File file = new File("mylog.txt");
FileWriter myFileWriter = null;
BufferedWriter myBufferedWriter = null;

try 
    //with FileWriter(File file, boolean append) you can writer to 
    //the end of the file
    myFileWriter = new FileWriter( file, true );
    myBufferedWriter = new BufferedWriter( myFileWriter );

    myBufferedWriter.write( trace );

catch ( IOException ex1 ) 
    //Do as you want. Do you want to use recursive to handle 
    //this exception? I don't advise that. Trust me...

finally 
    try 
        myBufferedWriter.close();
    
    catch ( IOException ex1 ) 
        //Idem...
    

    try 
        myFileWriter.close();
    
    catch ( IOException ex1 ) 
        //Idem...
    

我希望我有所帮助。

祝你有美好的一天。 :)

【讨论】:

以上是关于如何在 Java 6 中捕获所有已检查的异常(在一个块中)?的主要内容,如果未能解决你的问题,请参考以下文章

运行时/已检查/未检查/错误/异常之间的差异

自动捕获 BlazeDS 远程处理方法引发的所有异常?

如何在 FutureTask 中捕获异常

如何在java中识别已检查和未检查的异常?

异常抛出与捕获的思考

拦截 C# 中的所有异常,即使它们已经被捕获 [重复]