当sub方法抛出异常时,将封装在专用的"包中。异常被视为良好的实践?
public String doStuff() throws UtilsException {
try {
throw new NullPointerException("test");
} catch (NullPointerException e) {
throw new UtilsException("something occured", e);
}
}
//use this exception for all classes of this package / component
public class UtilsException extends Exception {
private static final long serialVersionUID = 1L;
public UtilsException() {
super();
}
public UtilsException(String message, Throwable cause) {
super(message, cause);
}
public UtilsException(String message) {
super(message);
}
public UtilsException(Throwable cause) {
super(cause);
}
}
Optional.empty()
可以替代避免投掷/捕获复杂的应用程序吗?
public Optional<String> doStuff() throws UtilsException {
try {
return Optional.of("ok");
} catch (NullPointerException e) {
LOG.error("Something append... {}", e.getMessage());
return Optional.empty();
}
}
答案 0 :(得分:1)
首先,你应该从不捕获NullPointerException(或者一般的运行时异常)和其他类似的返回。 好吧,也许很少有你需要这样做的情况(比如有缺陷的第三方api)。
当您的程序出现错误并且您应该让它们出现异常时(例如NullPointer,ClassCast,IllegalArgument等) 它们冒泡并在程序的某个高阶组件中处理它们。
话虽如此,(并且有臭名昭着的短语)取决于......
例外是&#34;负责任&#34;为了通知错误,因此他们需要提供信息,呼叫者将使用它们来决定做什么。请考虑以下事项:
public void readFile(String path) throws IOException {
// read file content
return content;
}
try {
return readFile("foo.txt");
} catch(FileNotFound e) {
// For this specific scenario not finding the file is not a problem
return "";
} catch(IOException e) {
// This we are not expecting to happen, if the file exists we should be
// able to read it, otherwise we should inform the user.
log.error(e);
display("We had a problem reading the file, Check the file permissions and try again");
}
正如您在上面的示例中所看到的,在这种情况下,您不希望将IOException包装在另一个异常中 因为您将删除客户端在发生错误时决定该怎么做的能力。
另外,请注意IOException是&#34; wrap&#34;的一种形式。因为异常也是对象,所以你可以使用继承 概括你的方法抛出什么样的错误,然后抛出更多特定的错误,以便调用者可以 决定做什么。
有些情况下,包装异常是一种很好的做法,并且是可行的方法。 例如,如果您要创建一个lib,其主要功能是获取天气信息。
对于第一个版本,您保持简单并使用第三方API来获取当天的值。 api的主要方法是这样的。
public Weather getWeather(Date day) throws HTTPException {
return weather.get(day);
}
你的api做得很好,但是你注意到你对天气api做了太多的请求 你将不得不很快开始付钱。然后,您决定将结果缓存在数据库表中 所以你可以减少请求数量。
public Weather getWeather(Date day) throws HTTPException, SQLException {
Weather w = getFromCache(day);
if (w != null) {
return w;
} else {
return getAndCache(day);
}
}
现在你遇到了问题,你不能将这个新的异常添加到throws语句中,因为你肯定会破坏 你api的用户代码。
如果您考虑一下,如果您从wheter api获取数据时遇到问题,那么您的api用户就不感兴趣了
从您的缓存中,他们只是想知道错误。这是将这些异常包装起来的一个非常好的案例
一个更通用的,如WeatherFetchException
。
正如您所看到的,这实际上取决于......
我的经验法则是,保持您的例外意义,如果您想要包装它们,请仅在 这是有道理的,什么时候它不会消除来电者处理错误的能力。
仅仅为了它而包装异常绝对不是一个好习惯。