如何避免使用try ... catch块

时间:2012-02-06 03:26:59

标签: java try-catch

我理解这些是必要的...当然要编写正确的代码,但有没有一种设计模式可以帮助避免在类中重复尝试try ... catch块?例如,我写了一个特殊的类,抛出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 catch块。

try {
    beanComparator.setIteratorFalseAction(falseAction);
                beanComparator.iterateComparatorResults(beanComparator.compareBeans(contact, compareContact));
} catch (IllegalArgumentException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} catch (IntrospectionException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}

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

6 个答案:

答案 0 :(得分:8)

我不确定你的例子是多么真实,但是没有必要a)分别捕获每个异常,如果你不区别地处理它们,或者b)在很多情况下捕获它们。 / p>

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

我遵循两条一般准则:

  1. 处理异常,如果可以的话(例如,关闭文件访问异常中的打开文件,或重试一个麻烦的界面(愚蠢的不可靠的定制USB设备...... < / em>的))。
  2. 允许异常冒泡到堆栈中更高的位置,您可以捕获所有无法处理的异常。记录它们,显示它们或杀死你的应用程序,无论什么是最有意义的。
  3. 我将用一些代码stolen from inspired by the Java tutorials来说明第二点。

    private String readFirstLineFromFile(String path) throws IOException
    {
        try (BufferedReader br = new BufferedReader(new FileReader(path)))
        {
            return br.readLine();
        }
    }
    

    在这里,我们定义了一种尝试从文件中读取的方法。这里有很多东西可能会出错,但是这个级别的代码没有什么可以做的。相反,它将使用throws子句将调用传递给调用它的方法。该调用方法可以处理异常本身,或者将降压传递给调用者,使用相同的子句:

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

    现在,lots of debate解释了在这种情况下Java需要throws的原因。许多其他语言不会使用它们,无论好坏。您经常会看到RuntimeExceptions - 不需要throws子句的异常。如果您的方法可能会引发从RuntimeException延伸的异常,那么需要在throws中声明该事实。

答案 1 :(得分:4)

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

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

答案 2 :(得分:2)

所有异常都扩展了类Exception(一些如何排除),所以你可以做的是:

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.
}

答案 3 :(得分:0)

您可以捕获它们并将它们重新抛出为RuntimeException,就像这样......

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

答案 4 :(得分:0)

如果您使用的是Java 7,则可以使用multiple exception catching。它简化了代码:

try {
    sql = (SQL) MethodUtils.invokeExactMethod(bean, "getSQL", (Object[])null);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
    e.printStackTrace();
}

这比捕获异常更好,因为你仍然只捕获你想要的异常。

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

答案 5 :(得分:0)

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

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

此处InvocationFaliureException是一个自定义异常,

public InvocationFaliureException extends Exception
{
....
}