java 将泛型用于异常是否明智?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6818251/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it wise to use generics for exceptions?
提问by Freiheit
My team is in the middle of cleaning up our use of throws Exception
and either removing or replacing them with specific exceptions.
我的团队正在清理我们对throws Exception
它们的使用,并使用特定的例外删除或替换它们。
A common throws is because an entity was not found. Should we be throwing a generic NotFoundException
or a specific SomeClassNotFoundException
for each entity class?
一个常见的抛出是因为没有找到实体。我们应该为每个实体类抛出泛型NotFoundException
还是特定SomeClassNotFoundException
的?
If we should be throwing a specific exception, should we be creating a specific Exception class for each entity type? Can we safely use generics? Like this class NotFoundException<T extends EntityBaseClass> extends Exception
and then the constructor takes care of declaring what Entity type we're dealing with?
如果我们应该抛出一个特定的异常,我们是否应该为每个实体类型创建一个特定的 Exception 类?我们可以安全地使用泛型吗?像这样class NotFoundException<T extends EntityBaseClass> extends Exception
然后构造函数负责声明我们正在处理的实体类型?
If we should be throwing a specific exception and not using generics, should those exceptions extend or implement a NotFoundException
abstract class or interface?
如果我们应该抛出一个特定的异常而不使用泛型,这些异常是否应该扩展或实现一个NotFoundException
抽象类或接口?
采纳答案by NPE
A simple litmus test for the question
问题的简单试金石
Should we be creating a specific Exception class for each entity type?
我们应该为每个实体类型创建一个特定的 Exception 类吗?
is
是
Are there any circumstances where we would need to write a
catch
clause that will catch a "not found" exception thrown by some class X and not by any other class?
在任何情况下,我们是否需要编写一个
catch
子句来捕获某个类 X而不是任何其他类抛出的“未找到”异常?
If the answer is "yes", then a separate ClassXNotFoundException
is warranted; otherwise, it probably isn't.
如果答案是“是”,则有ClassXNotFoundException
必要单独进行;否则,它可能不是。
As to the second half of your question, the language doesn't permit the use of generics for exception types.
至于您问题的后半部分,该语言不允许对异常类型使用泛型。
回答by axtavt
It's not allowed to make exceptions generic - it won't compile (JLS §8.1.2):
不允许将异常设为通用 - 它不会编译(JLS §8.1.2):
It is a compile-time error if a generic class is a direct or indirect subclass of Throwable
如果泛型类是 Throwable 的直接或间接子类,则会出现编译时错误
Since type parameters of generics are erased at runtime, there is no way to distinguish between generic exceptions with different type parameters in the catch
clause, thus generic exceptions are not supported. So, you actually have no choice regarding using generic exceptions.
由于泛型的类型参数在运行时被擦除,无法区分子catch
句中不同类型参数的泛型异常,因此不支持泛型异常。因此,对于使用通用异常,您实际上别无选择。
回答by Mike Samuel
should we be creating a specific
Exception
class for each entity type?
我们应该
Exception
为每个实体类型创建一个特定的类吗?
If the callers of your code can reasonably recover from a failure to locate an entity definition and would benefit from being able to take a different recovery strategy per entity type, then yes. Otherwise no.
如果您的代码的调用者可以从定位实体定义的失败中合理地恢复,并且能够从每个实体类型采用不同的恢复策略中受益,那么是的。否则没有。
Can we safely use generics? Like this class NotFoundException extends Exception and then the constructor takes care of declaring what Entity type we're dealing with?
我们可以安全地使用泛型吗?像这个类 NotFoundException 扩展 Exception 然后构造函数负责声明我们正在处理的实体类型?
It won't help callers of your code switch on the entity type related to the failure.
它不会帮助您的代码的调用者切换与失败相关的实体类型。
Even if you define an exception type MyParameterizedException<T>
then due to type-erasure, the caller cannot do
即使你定义了一个异常类型,MyParameterizedException<T>
然后由于类型擦除,调用者也不能做
try {
callYourCode();
} catch (MyParameterizedException<TypeA> ex) {
// some handling code
} catch (MyParameterizedException<TypeB> ex) {
// some different handling code for type b
}
because with type erasure it looks like
因为使用类型擦除它看起来像
try {
callYourCode();
} catch (MyParameterizedException ex) {
// some handling code
} catch (MyParameterizedException ex) {
// some different handling code for type b
}
and the second catch
block would be unreachable code and so will be rejected at compile time by javac
. The first catch block would be entered for type b and type a entities (and any other types as well).
并且第二个catch
块将是无法访问的代码,因此将在编译时被javac
. 将为类型 b 和类型 a 实体(以及任何其他类型)输入第一个 catch 块。
If we should be throwing a specific exception and not using generics, should those exceptions extend or implement a
NotFoundException
abstract class or interface?
如果我们应该抛出一个特定的异常而不使用泛型,这些异常是否应该扩展或实现一个
NotFoundException
抽象类或接口?
If the callers of your code would be surprised if they did not then yes.
如果您的代码的调用者不这样做会感到惊讶,那么是的。
If the callers of your code would benefit from having entity failures handled by code that handles other NotFoundException
s then yes.
如果您的代码的调用者将从处理其他NotFoundException
s的代码处理实体故障中受益,那么是。
If the callers of your code would likely not want to have failures to locate an entity type definition handled in the same way as other NotFound
conditions then no.
如果您的代码的调用者可能不希望以与其他NotFound
条件相同的方式处理实体类型定义失败,那么不。
回答by Marcelo
Instead of using:
而不是使用:
public Class EntityNotFoundException<T extends EntityBaseClass> extends Exception {
}
You should use:
你应该使用:
public Class EntityNotFoundException extends Exception {
private Class<? extends EntityBaseClass> clazz;
public EntityNotFoundException(Class<? extends EntityBaseClass> clazz) {
this.clazz = clazz;
}
. . .
}
This way you can keep a reference to the Entity type that is generating the exception. To throw one of this exceptions you can use:
通过这种方式,您可以保留对生成异常的实体类型的引用。要抛出此异常之一,您可以使用:
throw new EntityNotFoundException(Customer.class);
The compiler willvalidate that Customer does extend EntityBaseClass.
编译器将验证 Customer 确实扩展了 EntityBaseClass。
回答by Amir Raminfar
I think everybody answer is saying you don't need a specific exception. I was looking at how Hibernate defines not found exception. I found EntityNotFoundExceptionI would add that you should NOT even create your own exception, just reuse this one. It extends RuntimeException which means you are not forcing people to catch it. But if you want to then you can reuse an existing class in J2EE. Which is always better than writing new code.
我认为每个人的回答都是说你不需要特定的例外。我在看 Hibernate 如何定义未找到的异常。我发现EntityNotFoundException我想补充一点,你甚至不应该创建自己的异常,只需重用这个异常。它扩展了 RuntimeException,这意味着您不会强迫人们捕捉它。但是,如果您愿意,那么您可以重用 J2EE 中的现有类。这总是比编写新代码要好。