将generics用于exception是否明智?

我的团队正在清理我们对throws Exception的使用,并删除或替换它们以及特定的例外情况。

常见的抛出是因为找不到实体。 我们应该为每个实体类抛出一个通用的NotFoundException还是一个特定的SomeClassNotFoundException

如果我们应该抛出一个特定的exception,我们应该为每个实体类型创建一个特定的Exception类吗? 我们可以安全地使用generics吗? 像这样的class NotFoundException extends Exception然后构造函数负责声明我们正在处理的实体类型?

如果我们应该抛出一个特定的exception而不使用generics,那些exception是应该扩展还是实现NotFoundException抽象类或接口?

这个问题的一个简单的试金石

我们应该为每个实体类型创建一个特定的Exception类吗?

在任何情况下我们都需要编写一个catch子句来捕获某个类X 而不是任何其他类抛出的“未找到”exception吗?

如果答案为“是”,则保证单独的ClassXNotFoundException ; 否则,它可能不是。

至于问题的后半部分,该语言不允许对exception类型使用generics。

不允许将exception设为通用 – 它不会编译( JLS§8.1.2 ):

如果generics类是Throwable的直接或间接子类,则是编译时错误

由于generics的类型参数在运行时被擦除,因此无法区分catch子句中具有不同类型参数的genericsexception,因此不支持genericsexception。 因此,您实际上没有选择使用通用exception。

而不是使用:

 public Class EntityNotFoundException extends Exception { } 

你应该使用:

 public Class EntityNotFoundException extends Exception { private Class clazz; public EntityNotFoundException(Class clazz) { this.clazz = clazz; } . . . } 

这样,您可以保留对生成exception的实体类型的引用。 要抛出其中一个例外,您可以使用:

 throw new EntityNotFoundException(Customer.class); 

编译器validationCustomer是否扩展了EntityBaseClass。

我们应该为每个实体类型创建一个特定的Exception类吗?

如果您的代码的调用者可以合理地从找不到实体定义中恢复,并且可以从每个实体类型采用不同的恢复策略中受益,那么是。 否则没有。

我们可以安全地使用generics吗? 像这个类一样,NotFoundException扩展了Exception,然后构造函数负责声明我们正在处理的实体类型?

它不会帮助您的代码的调用者切换与失败相关的实体类型。

即使您定义了一个exception类型MyParameterizedException然后由于类型擦除,调用者也无法做到

  try { callYourCode(); } catch (MyParameterizedException ex) { // some handling code } catch (MyParameterizedException ex) { // some different handling code for type b } 

因为类型擦除它看起来像

  try { callYourCode(); } catch (MyParameterizedException ex) { // some handling code } catch (MyParameterizedException ex) { // some different handling code for type b } 

并且第二个catch块将是无法访问的代码,因此将在编译时被javac拒绝。 将为类型b输入第一个catch块并键入实体(以及任何其他类型)。

如果我们应该抛出一个特定的exception而不使用generics,那些exception是应该扩展还是实现NotFoundException抽象类或接口?

如果你的代码的调用者如果没有那么会感到惊讶然后是的。

如果您的代码的调用者将受益于处理其他NotFoundException的代码处理实体失败,那么是。

如果您的代码的调用者可能不希望无法找到以与其他NotFound条件相同的方式处理的实体类型定义,则不会。

我想每个人都回答说你不需要特定的例外。 我在看Hibernate如何定义未发现的exception。 我发现EntityNotFoundException我会补充说你甚至不应该创建自己的exception,只需重用这个exception。 它扩展了RuntimeException,这意味着你不会强迫人们捕获它。 但是,如果您愿意,可以重用J2EE中的现有类。 这总是比编写新代码更好。