我的团队正在清理我们对throws Exception
的使用,并删除或替换它们,但有特殊例外。
常见的抛出是因为找不到实体。我们应该为每个实体类抛出通用的NotFoundException
还是特定的SomeClassNotFoundException
?
如果我们应该抛出一个特定的异常,我们应该为每个实体类型创建一个特定的Exception类吗?我们可以安全地使用仿制药吗?像这样class NotFoundException<T extends EntityBaseClass> extends Exception
,然后构造函数负责声明我们正在处理的实体类型?
如果我们应该抛出一个特定的异常并且不使用泛型,那么这些异常是否应该扩展或实现NotFoundException
抽象类或接口?
答案 0 :(得分:23)
不允许将异常设为通用 - 它不会编译(JLS §8.1.2):
如果泛型类是Throwable
的直接或间接子类,则是编译时错误
由于泛型的类型参数在运行时被擦除,因此无法区分catch
子句中具有不同类型参数的泛型异常,因此不支持泛型异常。因此,您实际上没有选择使用通用异常。
答案 1 :(得分:11)
对问题的简单试金石
我们应该为每个实体类型创建一个特定的Exception类吗?
是
在任何情况下我们都需要编写一个
catch
子句来捕获某个类X 而不是任何其他类抛出的“未找到”异常?
如果答案为“是”,则需要单独的ClassXNotFoundException
;否则,它可能不是。
关于问题的后半部分,该语言不允许对异常类型使用泛型。
答案 2 :(得分:5)
我们应该为每个实体类型创建一个特定的
Exception
类吗?
如果您的代码的调用者可以合理地从找不到实体定义中恢复,并且可以从每个实体类型采用不同的恢复策略中受益,那么是。否则没有。
我们可以安全地使用泛型吗?像这个类一样,NotFoundException扩展了Exception,然后构造函数负责声明我们正在处理的实体类型?
它不会帮助您的代码的调用者切换与失败相关的实体类型。
即使你定义了一个异常类型MyParameterizedException<T>
,然后由于类型擦除,调用者也无法做到
try {
callYourCode();
} catch (MyParameterizedException<TypeA> ex) {
// some handling code
} catch (MyParameterizedException<TypeB> 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块并键入实体(以及任何其他类型)。
如果我们应该抛出一个特定的异常并且不使用泛型,那么这些异常是否应该扩展或实现
NotFoundException
抽象类或接口?
如果你的代码的调用者没有那么会感到惊讶,那么就是。
如果代码的调用者可以从处理其他NotFoundException
的代码处理实体失败中受益,那么就是。
如果您的代码的调用者可能不希望无法找到以与其他NotFound
条件相同的方式处理的实体类型定义,那么不会。
答案 3 :(得分:5)
而不是使用:
public Class EntityNotFoundException<T extends EntityBaseClass> extends Exception {
}
您应该使用:
public Class EntityNotFoundException extends Exception {
private Class<? extends EntityBaseClass> clazz;
public EntityNotFoundException(Class<? extends EntityBaseClass> clazz) {
this.clazz = clazz;
}
. . .
}
这样,您可以保留对生成异常的实体类型的引用。要抛出其中一个例外,您可以使用:
throw new EntityNotFoundException(Customer.class);
编译器将验证Customer是否扩展了EntityBaseClass。
答案 4 :(得分:0)
我想每个人都回答说你不需要特定的例外。我在看Hibernate如何定义未发现的异常。我发现EntityNotFoundException我想补充一点,你甚至不应该创建自己的异常,只需重用这个异常即可。它扩展了RuntimeException,这意味着你不会强迫人们捕获它。但是,如果您愿意,可以重用J2EE中的现有类。这总是比编写新代码更好。