我遍历了JDK中的所有内置异常,仅在大小超出预期长度时才找到SizeLimitExceededException
。但是,如果我想在大小限制小于预期长度时引发异常,那么没有可以调用的内置异常类吗?
SSN是9位数字的长度。如果输入的SSN短于9位数字,那么我想抛出此异常。
答案 0 :(得分:7)
虽然使用合适的例外是一种好习惯,并且您应该花一些时间(如您所愿)寻找合适的例外,但通常也无需过多考虑。
在您的示例中,如果您仅抛出new IllegalArgumentException("SSN is only of length <X> but length 9 is required")
,我认为这完全可以。它将使执行失败,并为您提供有意义的堆栈跟踪。
请注意,将异常用于控制流被视为bad practice。因此,请永远不要使用类似的
try {
person.setSSN(ssn);
catch (SSNTooShortException e) {
println("SSN too short! Please try again");
}
相反,在设置SSN之前,请使用自定义验证程序来检查SSN,并且仅使用异常来防止编程错误。
if (!SSNFormat.matches(ssn)) { // <-- whoops condition is inverted
person.setSSN(ssn);
}
该代码段有望在您的(单元)测试中很快失败,并且您将知道您的编程逻辑存在缺陷。
当然,取决于您的应用程序,可以并且应该使用许多验证器框架之一(而不是使用自定义验证器)(例如,查看Hibernate's constraints,但是实际上,所有大型框架都支持一种或另一种形式)。
答案 1 :(得分:2)
也许您想要类似IndexOutOfBoundsException之类的东西。抛出该错误指示某种数据的索引超出范围。 https://docs.oracle.com/javase/7/docs/api/java/lang/IndexOutOfBoundsException.html
答案 2 :(得分:2)
您可以将异常创建为
public class UnderBottomException extends Exception {
public UnderBottomException(int dim, int param) {
super();
System.out.println("you entered a length of : " + dim + " whereas the minimum length expected is : " + param);
}
}
此异常将在您的POJO中以这种方式实现:
public class Register {
private int[] registre;
private int minRange = 9;
public Register(int[] parametre) throws UnderBottomException {
if (parametre.length < this.minRange) {
throw new UnderBottomException(parametre.length, this.minRange);
}
else {
this.registre = new int[parametre.length];
for (int i = 0 ; i < this.registre.length; i++)
this.registre[i] = parametre[i];
}
}
public int[] getRegistre() {
return registre;
}
public int getMinRange() {
return minRange;
}
}
最后,您可以像这样使用对象捕获异常:
public class Main {
public static void main(String[] args) {
int[] a = {1,2,3,4,5,6,7,8};
try {
Register monRegistre = new Register(a);
System.out.println("Nickel le sous registre de rang 2 = " + monRegistre.getRegistre()[1]);
}
catch(UnderBottomException e) {
}
}
}
输出:
you entered a length of : 8 whereas the minimum length expected is : 9
答案 3 :(得分:2)
假设有一个内置的JDK SizeLimitSubceededException
(我刚刚了解到,超越是相反的)。您的检查SSN长度的代码是否会抛出一个异常-SizeLimitExceededException
-如果大小超出预期大小,而另一个异常-SizeLimitSubceededException
-如果该大小超过预期大小?
这很尴尬:
throws
子句中指定这两个异常(假设SizeLimitSubceededException
是经过检查的异常,与SizeLimitExceededException
相同)。如果大小正确但又有其他问题,该怎么办-例如,SNN包含非数字字符?您会为此抛出第三个例外吗?
我的观点是,最好从设置SSN的方法中抛出一种异常类型。
如果您希望将其作为检查异常(我建议这样做,以迫使调用方对其进行处理),则建议定义自己的自定义异常-可能是InvalidSSNException
。此异常可以具有一个带有多个参数的构造函数-其中一个是无效的SSN,另一个可以是boolean
,用于指示是否由于长度错误而引发了异常。
然后,您的自定义异常会产生与失败原因匹配的错误消息:
如果输入的SSN长度错误(长度是否太长都没有关系),则消息将指定预期的长度(9)。
如果输入的SSN长度正确,则消息将指定有效字符(仅数字)。
示例:
class Person {
...
public setSSN (String ssn) throws InvalidSSNException
{
if (ssn == null) {
throw new InvalidSSNException (ssn, false);
}
if (ssn.length() != 9) {
// exception thrown as a result of invalid length
throw new InvalidSSNException (ssn, true);
}
for (char c : ssn.toCharArray()) {
if (c < '0' || c > '9') {
// exception thrown as a result of invalid character
throw new InvalidSSNException (ssn, false);
}
}
this.ssn = ssn;
}
...
}