2010-10-14 115 views
2

我完全不熟悉此代码,并开始质疑原始开发人员的设计选择。在Java中处理运行时异常的正确方法

我有一个多线程的Java应用程序,它处理许多任务。我的工作是修复代码中的异常处理,以便在发生RuntimeException(iBatis和/或NullPointerException)时执行其余任务而不是线程终止。我想知道什么是对付下面的异常处理的最佳方式:

public List<WorkUnit> performModule(List<WorkUnit> listOfInputs) 
      throws ModuleException { 

     List<WorkUnit> listOfOutputs = new ArrayList<WorkUnit>(); 
     for (WorkUnit mi : listOfInputs) { 
      WorkUnit mo=null; 
      try { 
       if (mi instanceof BulkOrder) { 
        mo = performModuleOperation(...); 
       } else if (mi instanceof Order) { 
        mo = performModuleOperation(...); 
       } else if (mi instanceof PreReleaseLoad) { 
        mo = performModuleOperation(...); 
       } else if (mi instanceof Load) { 
        mo = performModuleOperation(...); 
       } 
       listOfOutputs.add(mo); 
      } catch (OMSException e) { 
        if (e.shouldProcessFurther()) { 
         listOfOutputs.add((mo!=null) ? mo : mi); 
        } 
       //save error to database - code was removed 
        if (e.getExceptionType().equals(ExceptionType.TECHNICAL)) { 
         if (e instanceof ModuleException) { 
          throw (ModuleException) e; 
         } else { 
         throw new ModuleException(e); 
         } 
        } 
      } catch (Throwable th) { 
       ModuleException me = new ModuleException(th); 
       ExceptionHandler.logException(me, (WorkUnit)mi,orderDelegate); 
       throw me; 
      } 

     } 
     return listOfOutputs ; 
    } 

我有两个主要问题。 1)Throwable对象的catch。我知道他们想要捕获检查的异常和未检查的异常。我猜他们也想检查错误,但是Sun的异常处理文档明确指出这是非常不利的。如果出现像JVM内存不足等严重错误,您可能无法恢复。这可能会被记录在日志文件中,我不同意它需要处理。就个人而言,如果您正在跟踪技术和应用程序异常,那么错误看起来不像您要监视的任何其他异常。我可能是错的......

2)目前还不清楚如何处理异常。在下面的代码中,对上面的代码抛出异常,它包装了一个常规的异常,无论是选中还是取消选中自定义异常并引发异常。上面的代码查找一个OMSException,它是整个应用程序中每个自定义异常的父代。这是一个很好的设计吗?您可以看到它们在自定义异常对象中包含ExceptionType的位置。目前Java的现有异常处理似乎已经内置了一项功能。如果它是应用程序异常,则抛出一个自定义异常。如果它是一个技术异常,那么当它不是假设或数据库连接问题时,就是null,然后从Java中捕获一个未经检查的异常并作出相应的反应。整个事情似乎令人困惑。我只想知道其他人对整个事情有什么想法。

public Order performModuleOperation(Order order) 
      throws ModuleException {         

     try { 
      Map<String, Rule> rules = ...      

     }  
     catch (InductException ie) { 
      throw ie; 
     } 
     catch (Exception e) {  
      e.printStackTrace(); 
      throw new InductException(e.toString(),e); 
     } 
     return order; 
    } 
+0

上有这么多线程/类似的话题。你的异常有这个方法 - e.shouldProcessFurther() - 通常它应该由处理程序决定是继续还是中止或是其他适当的动作。例外情况下,设置和获取严重性,错误代码等可能对用户案例有用。 – Jayan 2010-10-14 04:40:37

回答

2

有处理与未检测异常退出线程两种方式。第一个选项是从与在try-catch块捕获所有的错误和异常运行的线程:

Thread t = new MyThread(); 
try { 
    lauchThreadHere(t); 
} catch (Throwable e) { 
    // log `e` or re-launch thread `t` or do something else. 
} 

另一种方法是实现Thread.UncaughtExceptionHandler

public class MyUeh implements Thread.UncaughtExceptionHandler { 
    public void uncaughtException(Thread t, Throwable e) { 
     // log `e` or re-launch thread `t` or do something else. 
    } 
} 

Thread t = new MyThread(); 
t.setUncaughtExceptionHandler(new MyUeh()); 
lauchThreadHere(t);