内置异常长度比预期的短吗?

时间:2019-12-12 22:05:05

标签: java exception

我遍历了JDK中的所有内置异常,仅在大小超出预期长度时才找到SizeLimitExceededException。但是,如果我想在大小限制小于预期长度时引发异常,那么没有可以调用的内置异常类吗?

更新:

SSN是9位数字的长度。如果输入的SSN短于9位数字,那么我想抛出此异常。

4 个答案:

答案 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-如果该大小超过预期大小?

这很尴尬:

  1. 您必须在方法的throws子句中指定这两个异常(假设SizeLimitSubceededException是经过检查的异常,与SizeLimitExceededException相同)。
  2. 方法的调用者必须处理两个异常。

如果大小正确但又有其他问题,该怎么办-例如,SNN包含非数字字符?您会为此抛出第三个例外吗?

我的观点是,最好从设置SSN的方法中抛出一种异常类型。

如果您希望将其作为检查异常(我建议这样做,以迫使调用方对其进行处理),则建议定义自己的自定义异常-可能是InvalidSSNException。此异常可以具有一个带有多个参数的构造函数-其中一个是无效的SSN,另一个可以是boolean,用于指示是否由于长度错误而引发了异常。

然后,您的自定义异常会产生与失败原因匹配的错误消息:

  1. 如果输入的SSN长度错误(长度是否太长都没有关系),则消息将指定预期的长度(9)。

  2. 如果输入的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;
    }
    ...

}