我有一个方法,它将异常作为特定方法的参数。此方法需要根据异常类型执行不同的逻辑。在以下两种处理方式之间..什么是最有效的方式(有第三种更好的方式)..以及为什么
public void processException(Exception ex) {
try {
throw ex;
} catch(CustomException e1) {
//do something
} catch (CustomException2 e2) {
//do something else
}
}
或
public void processException(Exception ex) {
if (ex instanceof CustomException) {
// do something
} else if (ex instanceof CustomException2) {
// do something else
}
}
答案 0 :(得分:7)
除了效率之外,第二种方式是首选,因为异常不会在非特殊情况下抛出。 “调度”的第一种方法是在常规控制流中使用异常抛出,这使得读取程序变得更加困难。
此外,这两个方法并不相同:第一个程序必须声明为抛出一个已检查的异常,因为并非所有子类型都由catch
块处理。
如果您正在处理程序定义的自定义异常,您可以避免检查子类型:因为Exception
对象是常规类,您可以向它们添加包可见方法,并拥有它们实现一个包含该方法的包可见接口。然后,异常将覆盖该方法,允许您使用常规的“虚拟”分派,而不是在运行时检查确切的类类型。
以下是此方法的示例:假设您希望将异常写入日志文件。您可以按如下方式执行此操作:
interface LoggableException {
void logToFile();
}
public class CustomExceptionOne extends Exception implements LoggableException {
...
public void logToFile() {
// Do something
}
}
public class CustomExceptionTwo extends Exception implements LoggableException {
...
public void logToFile() {
// Do something else
}
}
public void processException(Exception ex) {
if (ex instanceof LoggableException) {
LoggableException lEx = (LoggableException)ex;
lEx.logToFile();
}
}
答案 1 :(得分:4)
第一个是一个非常糟糕的主意。逻辑不应表示为异常捕获。无论你是否意识到,它们都很昂贵。
我也不喜欢第二个。当你看到if / else逻辑时,你应该考虑多态性。
答案 2 :(得分:2)
显然第二种选择更好。所有异常最终都是对象,更好,更安全,建议执行检查实例以确定对象的类型。
答案 3 :(得分:1)
投掷和捕获例外是昂贵的操作,只应在特殊情况下发生。此外,可能正在调用处理异常的方法,因为已经抛出了异常。我不会再扔了。
像rgettman建议的instanceof或者重载的processException。另一种选择是
public void processException(Exception e) {
Class eClass = e.getClass();
if (eClass == CustomeException.class) { // This exception is most likely.
// do something
} else if (eClass == CustomException2.class) {
// do something
} else if (eClass == CustomException3.class) {
// do something
} else if (eClass == CustomException4.class) {
// do something
}
}
我建议使用最可能的异常类来短接if/else if
语句。