在这种情况下,是否可以从构造函数中抛出异常?

时间:2014-05-22 21:07:17

标签: java exception constructor

在为学校项目开设课程(如学校课程)数据库系统时,我偶然发现了一个争论问题。

我有一个名为Course的课程。这是类的构造函数(另一个是为空值构造函数指定默认值):

public Course(String name, String code, char level, int academicYear)
{
    serialNumber = nextSerialNumber++;
    if (name == null) 
    {
        throw new NullPointerException("Name can not be null.");
    }
    else
    {
        this.name = name;
    }  
    if (code == null)
    {
        throw new NullPointerException("Code can not be null.");
    }
    else
    {
        this.code = code;
    }
    if (indexOf(level, VALID_LEVEL) == -1)
    {
        throw new InvalidLevelException("Level must be one of " 
            + "characters defined in the public array in Course.");
    }
    else
    {
        this.level = level;
    }
    if (String.valueOf(academicYear).length() != NUMBER_OF_DIGITS_IN_YEAR)
    {
        throw new InvalidYearException("Year must be a four digit number!");
    }
    else
    {
        this.academicYear = academicYear;
    }
}

其中

InvalidLevelException

InvalidYearException

是自定义异常,是

的子类
RuntimeException

我从该构造函数中抛出异常以指示是否有任何错误。例如,如果在读取数据文件时遇到错误数据,我可以拒绝它并将其写入日志(如项目所要求的),只需将该构造函数放在try-catch块中然后捕获这些异常即可,并在该catch块内,记录不良数据。

在向我的老师展示此代码后,他说从构造函数中抛出异常是不合适的。但是,我已阅读了许多鼓励这种做法的Stackoverflow帖子。

我的问题是:从上面的构造函数中抛出异常是否可以?

非常感谢附有答案的信誉良好的来源(例如,官方文件或权威书籍)。

非常感谢。

2 个答案:

答案 0 :(得分:3)

  

可以从上面的构造函数中抛出异常吗?

您的问题涉及Exception处理的一个方面。另一方面是准确地描述问题。我将简要介绍一下。

代码失败时会抛出异常吗?

这样做的原因很简单。您希望用户确切地知道问题发生的位置,如果您在整个地方传播异常,那么您将使代码用户更难以解释问题所在。如果问题出在对象的构造函数中,则表示在该对象的创建过程中出现了问题。

这为用户提供了一个重要的线索,这就是你所能做的。您不知道用户将如何错误地使用您的代码,因此您需要尽可能轻松地解释其问题的

异常消息是否描述了问题?

使用适当类型的Exception非常重要。如果他们提供了无效参数,请抛出IllegalArgumentException。如果他们提供了空值,则抛出NullPointerExceptionException在描述问题时应该尽可能有效。

第二部分是您附上的信息。我见过的次数:

Exception: Exception Occurred

令人沮丧地高涨。它没有任何帮助,并且是处理代码的极其懒惰的方式。你需要说清楚:

NullPointerException: Parameter X was null

即时,用户知道他们为X传递的值为null。简而言之,请确保该消息专门描述了导致该问题的问题。

额外阅读

  • 有关此主题的更多详细信息,请查看this link以获取有关异常处理的最佳做法。这有助于解决您遇到的任何其他问题。

答案 1 :(得分:3)

我没有看到在构造函数中抛出异常有什么问题。这意味着无法在有效状态下创建对象。

就个人而言,您抛出正确的异常,但如果您可以使用Java异常InvalidLevelException并且InvalidYearException应替换为IllegalArgumentExceptionNullPointerExceptionpublic Course(String name, String code, char level, int academicYear) { if (name == null) { throw new NullPointerException("Name can not be null."); } if (code == null) { throw new NullPointerException("Code can not be null."); } if (indexOf(level, VALID_LEVEL) == -1) { throw new InvalidLevelException("Level must be one of " + "characters defined in the public array in Course."); } if (String.valueOf(academicYear).length() != NUMBER_OF_DIGITS_IN_YEAR) { throw new InvalidYearException("Year must be a four digit number!"); } serialNumber = nextSerialNumber++; this.code = code; this.academicYear = academicYear; this.level = level; this.name = name; } ,则不要使用自定义异常如果参数为null,则为正确的异常。

我要改变的另一件事是风格:检查你的论据然后做其他所有事情。

187     public More ...HashMap(int initialCapacity, float loadFactor) {
188         if (initialCapacity < 0)
189             throw new IllegalArgumentException("Illegal initial capacity: " +
190                                                initialCapacity);
191         if (initialCapacity > MAXIMUM_CAPACITY)
192             initialCapacity = MAXIMUM_CAPACITY;
193         if (loadFactor <= 0 || Float.isNaN(loadFactor))
194             throw new IllegalArgumentException("Illegal load factor: " +
195                                                loadFactor);
196 
197         // Find a power of 2 >= initialCapacity
198         int capacity = 1;
199         while (capacity < initialCapacity)
200             capacity <<= 1;
201 
202         this.loadFactor = loadFactor;
203         threshold = (int)(capacity * loadFactor);
204         table = new Entry[capacity];
205         init();
206     }

(如果无法创建对象,为什么要增加序列号?)

它非常优雅吗? - 另一件事是让消息更具体。

无论如何,我认为最好的源代码是整个JDK平台,因为它是在构造函数中抛出异常的常见模式。


正如Luiggi Mendoza在评论中所说,如果你需要老师的教授,那就是HashMap constructor

{{1}}