当我没有捕捉到预期的异常类型时,为什么 IntelliJ 会显示编译错误?
Why does IntelliJ show a compilation error when I don't catch an expected exception type?
在 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) {
}
对我来说,EntityNotFoundException
的空 catch
语句是一种代码味道,我宁愿删除它并允许抛出异常。
然而,当我删除该 catch 语句时,它会导致编译器错误,而且我没有看到任何关于为什么删除该语句无效的解释或理由。
datastore.get
正在调用实现 com.google.appengine.api.datastore.DatastoreService
接口的东西,这意味着可能会抛出 EntityNotFoundException
,如果我们查看构造函数可以看出接口中定义:
com.google.appengine.api.datastore.DatastoreService
public interface DatastoreService extends BaseDatastoreService {
Entity get(Key var1) throws EntityNotFoundException;
为什么我 需要 捕获异常?为什么会出现编译错误?
Java 有两种不同的异常:checked 和 unchecked.
检查异常:
- 不从
java.lang.Error
或 java.lang.RuntimeException
扩展的任何 java.lang.Throwable
。
- 必须在可以抛出的地方明确处理。不这样做会导致编译错误。如果已检查异常在 try-catch 块中被捕获,或者如果包含方法声明为
throws
已检查异常,则会处理已检查异常。
未经检查的异常:
java.lang.Error
或 java.lang.RuntimeException
的任何实例。
- 可以被捕获和处理,但没有必要。也可以用在方法签名的
throws
子句中,但这样做通常被认为是不好的做法。如果有人想记录方法抛出未经检查的异常的可能性,他们应该在 Javadoc 中通过 @throws
. 进行记录
基于编译错误,我只能假设 EntityNotFoundException
是一个 checked 异常,因此必须进行处理。有关详细信息,请参阅 Java: checked vs unchecked exception explanation。
我同意空的 catch 块很臭。至少,您应该记录异常。如果你最终对每个可能的异常做同样的事情,你可以像这样重写 try-catch:
try {
/* Do stuff... */
} catch (EntityNotFoundException | IntantiationException | IllegalAccessException ex) {
// log ex...
}
以上语法需要 Java 7+,我相信。
在 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) {
}
对我来说,EntityNotFoundException
的空 catch
语句是一种代码味道,我宁愿删除它并允许抛出异常。
然而,当我删除该 catch 语句时,它会导致编译器错误,而且我没有看到任何关于为什么删除该语句无效的解释或理由。
datastore.get
正在调用实现 com.google.appengine.api.datastore.DatastoreService
接口的东西,这意味着可能会抛出 EntityNotFoundException
,如果我们查看构造函数可以看出接口中定义:
com.google.appengine.api.datastore.DatastoreService
public interface DatastoreService extends BaseDatastoreService {
Entity get(Key var1) throws EntityNotFoundException;
为什么我 需要 捕获异常?为什么会出现编译错误?
Java 有两种不同的异常:checked 和 unchecked.
检查异常:
- 不从
java.lang.Error
或java.lang.RuntimeException
扩展的任何java.lang.Throwable
。 - 必须在可以抛出的地方明确处理。不这样做会导致编译错误。如果已检查异常在 try-catch 块中被捕获,或者如果包含方法声明为
throws
已检查异常,则会处理已检查异常。
- 不从
未经检查的异常:
java.lang.Error
或java.lang.RuntimeException
的任何实例。- 可以被捕获和处理,但没有必要。也可以用在方法签名的
throws
子句中,但这样做通常被认为是不好的做法。如果有人想记录方法抛出未经检查的异常的可能性,他们应该在 Javadoc 中通过@throws
. 进行记录
基于编译错误,我只能假设 EntityNotFoundException
是一个 checked 异常,因此必须进行处理。有关详细信息,请参阅 Java: checked vs unchecked exception explanation。
我同意空的 catch 块很臭。至少,您应该记录异常。如果你最终对每个可能的异常做同样的事情,你可以像这样重写 try-catch:
try {
/* Do stuff... */
} catch (EntityNotFoundException | IntantiationException | IllegalAccessException ex) {
// log ex...
}
以上语法需要 Java 7+,我相信。