java - 当我没有捕获预期的异常类型时,为什么 IntelliJ 会显示编译错误?
问题描述
在 IntelliJ 中,我正在处理一些从 Google Cloud DataStore 检索实体的代码,使用try
catch
如下块:
try {
T dataAccessObject = class.newInstance();
entity = datastore.get(KeyFactory.createKey(dataAccessObject.GetEntityName().toString(), id));
dataModel = (T)dataAccessObject.ToModel(entity);
return dataModel;
} catch (EntityNotFoundException e) {
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
}
对我来说,空catch
语句EntityNotFoundException
是代码异味,我宁愿删除它并允许抛出异常。
但是,当我删除该 catch 语句时,它会导致编译器错误,并且我没有看到任何关于为什么删除该语句无效的解释或理由。
datastore.get
正在调用实现接口的东西,com.google.appengine.api.datastore.DatastoreService
这意味着可能EntityNotFoundException
会抛出 an ,如果我们查看接口中定义的构造函数可以看出这一点:
com.google.appengine.api.datastore.DatastoreService
public interface DatastoreService extends BaseDatastoreService {
Entity get(Key var1) throws EntityNotFoundException;
为什么我需要捕获异常呢?为什么会出现编译错误?
解决方案
Java 有两种不同的异常:checked和unchecked。
检查异常:
- 任何
java.lang.Throwable
不从java.lang.Error
或延伸的东西java.lang.RuntimeException
。 - 必须在可以抛出它们的地方显式处理。不这样做会导致编译错误。如果在 try-catch 块中捕获了已检查的异常,或者将包含方法声明为
throws
已检查的异常,则会处理已检查的异常。
- 任何
未经检查的异常:
java.lang.Error
或的任何实例java.lang.RuntimeException
。- 可以被抓住和处理,但不是必须的。也可以在
throws
方法签名的子句中使用,但这样做通常被认为是不好的做法。如果想要记录方法抛出未经检查的异常的可能性,他们应该在 Javadoc 中这样做,通过@throws
.
基于编译错误,我只能假设EntityNotFoundException
是一个检查异常,因此必须处理。有关详细信息,请参阅Java:已检查与未检查的异常说明。
我同意空的 catch 块很臭。至少,您应该记录异常。如果你最终对每个可能的异常都做同样的事情,你可以像这样重写 try-catch:
try {
/* Do stuff... */
} catch (EntityNotFoundException | IntantiationException | IllegalAccessException ex) {
// log ex...
}
我相信上面的语法需要Java 7+。
推荐阅读
- android - 在导航抽屉中,三个破折号或抽屉图标未显示
- javascript - html 内容在 iframe 中呈现,但不在 div 中
- r - 在 R 中导出时使用 df 名称作为文件名
- functional-programming - 球拍中的“减少中缀”?
- ios - 相当于在 Swift Combine 中使用 @Published 计算的属性?
- prestashop - Prestashop 1.6。多语言网站 - 未重定向到正确的主题模板
- java - 我计算一个非常大的斐波那契数模的算法太慢了
- python - 如何在循环中指定未知大小的列表
- python - 为属性提供自定义 __str__ 表示
- javascript - react-router 渲染导致子组件无法访问构造函数中的 redux 道具