Java 如何避免使用try…catch块

Java 如何避免使用try…catch块,java,try-catch,Java,Try Catch,我理解这些是必要的…当然要编写正确的代码,但是有没有一种设计模式可以帮助避免在类中重复尝试…捕获块?例如,我编写了一个抛出5个不同异常的特定类 public void iterateComparatorResults(ArrayList<ComparatorValue> results) throws IOException, IllegalArgumentException, IntrospectionException, IllegalAccessException, Invoc

我理解这些是必要的…当然要编写正确的代码,但是有没有一种设计模式可以帮助避免在类中重复尝试…捕获块?例如,我编写了一个抛出5个不同异常的特定类

public void iterateComparatorResults(ArrayList<ComparatorValue> results) throws IOException, IllegalArgumentException, IntrospectionException, IllegalAccessException, InvocationTargetException {
    Iterator<ComparatorValue> iterator = results.iterator();
    for(int i=0; i<results.size(); i++) {
        //Set data variables.
        setBeans(results.get(i).getClientBean(), results.get(i).getServerBean());
        setValues(results.get(i).getClientValue(), results.get(i).getServerValue());

        if(results.get(i).isMatch()) {
            //Data matches.
            runIteratorTrueAction();
        } else if(results.get(i).getInnerBeans() != null){
            //Value is a nested bean. Iterate again.
            ArrayList<ArrayList<ComparatorValue>> innerResults = results.get(i).getInnerBeans();
            for(int r=0; r<innerResults.size(); r++) {
                iterateComparatorResults(innerResults.get(r));
            }

        } else {
            //Data does not match.
            runIteratorFalseAction();
        }
    }
}

我希望有一些设计模式可以实现,这样我就可以创建一个单独的类或其他东西,并将所有try块隐藏在一个地方,然后引用该类并使用try块,而不必实际编写它们。与Spring等其他框架的做法类似?我只需要一点关于如何做的指导,因为我甚至不知道从哪里开始。

您可以捕获它们并将其作为运行时异常重新播放,如下所示

 try {
     sql = (SQL) MethodUtils.invokeExactMethod(bean, "getSQL", (Object[])null);
 } catch(Exception e){
     throw new RuntimeException(e);
 }

如果您使用的是JDK-7,那么可以像这样包装catch块

catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
} 

我不确定您的示例的真实性,但是没有必要a)单独捕获每个异常(如果您不以不同方式处理它们),或者b)在许多情况下捕获它们

在示例中,仅打印堆栈跟踪在几乎所有情况下都是一个坏主意。你正在把杂乱的信息打印到一个没人注意的地方

我遵循两条一般准则:

  • 如果可以的话,在抛出异常的位置处理异常(例如,在文件访问异常时关闭打开的文件,或者重试麻烦的接口(愚蠢、不可靠的定制USB设备…)
  • 允许异常冒泡到堆栈中更高的一个点,在这里可以捕获所有无法处理的异常。记录它们、显示它们或终止您的应用程序,这一切都是最有意义的 我将用一些代码来说明第二点

    在这里,我们定义了一个尝试从文件读取的方法。这里很多事情都可能出错,但这一级别的代码对此无能为力。相反,它将通过
    抛出
    子句把责任推给调用它的方法。该调用方法可以处理异常本身,或者使用相同的子句将责任传递给其调用方:

    private String readAllTheFiles() throws IOException
    {
        for (...)
        {
            readFirstLineFromFile(...);
        }
    }
    

    现在,这就是为什么Java在本例中需要
    抛出
    。不管是好是坏,许多其他语言都不使用它们。您经常会看到
    运行时异常
    ——不需要
    抛出
    子句的异常。如果您的方法可能抛出一个从
    RuntimeException
    扩展而来的异常,那么您不需要在
    throws
    中声明该事实,如果您使用的是Java 7,您可以使用。它将代码简化为:

    try {
        sql = (SQL) MethodUtils.invokeExactMethod(bean, "getSQL", (Object[])null);
    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
        e.printStackTrace();
    }
    
    这比只捕获异常要好,因为您仍然只捕获您想要的异常


    此外,您可能实际上不想捕获这样的异常,除了记录它们之外,不想处理它们。您最好执行一些错误处理,或者将它们抛出给调用方法,让它来处理。

    所有异常都扩展了类异常(一些是如何扩展的),因此您可以做的是:

    try {
        sql = (SQL) MethodUtils.invokeExactMethod(bean, "getSQL", (Object[])null);
    } catch (Exception e) {
        e.printStackTrace();
    } 
    
    您还可以向方法添加throws语句,以便调用您的类方法的任何人都可以在其代码中添加try-catch

    void myMethod() throws NoSuchMethodException, IllegalAccessException,
                           InvocationTargetException {
        //  Do stuff that can throw an exception.
    }
    

    我认为您应该创建一个自定义异常,当捕获到异常时,最好将异常抛出到上层,以便在UI中正确处理

    try {
        sql = (SQL) MethodUtils.invokeExactMethod(bean, "getSQL", (Object[])null);
    } catch (Exception e) {
        throw new InvocationFaliureException(e);
    }
    
    这里调用FaliureException是一个自定义异常

    public InvocationFaliureException extends Exception
    {
    ....
    }
    

    您是否要编写另一个try{}catch(){}来捕获RuntimeException???不需要尝试创建新类。刚才提到这是一个例子,说明我可以如何做到这一点。我可能应该说得更具体些。@FahimParkar我只是假设他试图逃避Java的“检查异常”功能。其他语言不需要捕获所有异常。当运行时异常模拟检查的异常时,重新引用检查的异常。您不能将这些行放在方法中吗。。?不要重复它们,而是使用特定的参数(即要调用的方法名称、要传递给该方法的参数等)调用该方法。您不需要捕获IllegalArgumentException,除非您希望它经常发生,因为它是
    运行时异常
    +1。这真的是唯一的出路。如果您在捕获异常时没有主动从异常中恢复,则根本不用费心捕获它。显然,我需要在这个问题上进行一些教育。我明白你的意思。老实说,当我的IDE告诉我需要捕获异常时,我确实需要。我能得到更详细的回答,只是为了给我一些关于如何实现正确的错误捕获系统的指导,或者可能是一个到资源的链接吗?比如,我应该在哪里存储数据,我应该传递什么类型的数据?我不太理解第二条准则?@ryandlf,你的IDE不是说你需要捕捉异常,而是说你需要捕捉异常或者声明你的方法抛出异常。我将更新我的答案。我还添加了一些额外的代码,以便更好地说明另一种情况,即代码由于异常而看起来很混乱。@ryandlf,我已经扩展了我的答案(希望)以解决您的评论和问题。这似乎更好一些。通过在一个自定义异常中捕获特定异常,我将如何以不同的方式处理它们?例如,参考我问题中的代码,我有5个不同的例外。我如何编写自定义类来处理第一个与第五个不同的类,并知道它们之间的区别?我从不承认我这样做,但使用“main()抛出异常{”可以很快解决问题。每次……是的;0
    try {
        sql = (SQL) MethodUtils.invokeExactMethod(bean, "getSQL", (Object[])null);
    } catch (Exception e) {
        throw new InvocationFaliureException(e);
    }
    
    public InvocationFaliureException extends Exception
    {
    ....
    }