如何在Java上验证构造函数参数?

Ern*_*zys 2 java validation

假设我们使用Java SE(无库),并且有以下情况。我们有一堂课:

public class DriverInfo {
    private final int age;

    public DriverInfo(int age) {
        this.age = age;
    }

    // getter here
}
Run Code Online (Sandbox Code Playgroud)

在某些国家/地区,您必须年满18岁才能开车。换句话说-我们需要对年龄参数进行一些验证。就像是:

if (age < 18) {
    throw new IllegalArgumentException("Age is not valid!");
}
Run Code Online (Sandbox Code Playgroud)

因此,我的问题是-此验证应该在哪里?我的想法如下:

  • 在构造函数上添加上述if()。如果从代码的多个位置调用构造函数,则验证将起作用。我担心的是,类构造函数(IMHO)不应包含任何逻辑。我对吗?
  • 验证构造函数外部的某个位置-无论是工厂方法,构建器类等。但是随后,我们强制开发人员不要通过使用构造函数实例化该类,而要使用一些人工工厂/构建器。
  • 通过使用Validate验证构造函数的参数。它不是标准的Java,但我看到有人这样做。对我来说,它看起来不正确,因为我们正在向构造函数添加逻辑-这对我来说不合适。
  • 还有其他我错过的好方法吗?

任何想法将不胜感激。有谁能提出最佳做法,以应对所描述的情况?

Iga*_*and 5

构造函数中的验证完全可以。此“构造函数中无逻辑”规则不适用于此规则,很遗憾,它的措词有点遗憾。构造函数的任务是从外部获取依赖项(依赖性注入),确保它们有效,然后将其存储在实例属性中- 简而言之,创建有效实例

这样,有效对象和无效对象的规则将保留在对象内部,而不是在某些工厂中分离的。

如果该实例无效,则抛出一个异常,该异常解释了参数的问题,绝对可以。它可以防止无效实例在系统中漫游。

同样,对于不可变对象,通过这种方式,您可以确保所有现有实例始终有效,这很棒。

在对象上具有某种验证方法是可能的,并且可能会很有用,但我希望每天都进行构造函数验证。但是,如果不可能,那么总比没有好,它仍然将有效性规则保留在对象内。就像某些框架为您构造可变对象并需要无参数构造函数时一样……您可以忘记调用它,但是总比没有好。