我理解这些是必要的...当然要编写正确的代码,但有没有一种设计模式可以帮助避免在类中重复尝试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这样的其他框架的方式吗?我只需要一点指示如何做到这一点,因为我甚至不知道从哪里开始。
答案 0 :(得分:8)
我不确定你的例子是多么真实,但是没有必要a)分别捕获每个异常,如果你不区别地处理它们,或者b)在很多情况下捕获它们。 / p>
您在示例中所做的只是打印堆栈跟踪,几乎在所有情况下都是一个坏主意。你将凌乱的信息打印到一个没人注意的地方。
我遵循两条一般准则:
我将用一些代码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
{
....
}