将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 extends EntityBaseClass> clazz; public EntityNotFoundException(Class extends EntityBaseClass> 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中的现有类。 这总是比编写新代码更好。