为什么java记录的规范构造函数的访问权限不能比记录级别更严格?

pokxtpni  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(462)

我有一种情况,我希望特定类型的记录示例只能在同一个包中的单独类中使用工厂方法创建。这是因为在创建记录之前,我需要执行大量的验证。
记录的目的是作为其已验证字段的哑数据载体,但验证不能在记录的构造函数中进行,因为我们需要访问一些复杂的验证程序对象才能实际执行验证。
因为将验证器对象传递给记录构造函数意味着它们将构成记录状态的一部分,这意味着我们不能使用记录构造函数来执行记录的验证。
因此,我将验证提取到自己的工厂中,并编写如下代码(同一个包中的工厂类和记录):

package some.package;

// imports.....

@Component
class SomeRecordFactory {
    private final SomeValidator someValidator;
    private final SomeOtherValidator someOtherValidator;
    // Rest of the fields
    // ....

    // constructor  
    // ....

    public SomeRecord create(...) {
         someValidator.validate(....);
         someOtherValidator.validate(....);
         // .... other validation

         return new SomeRecord(...);
    }
}
package some.package;

public record SomeRecord(...) {
    /* package-private */ SomeRecord {
    }
}

无论出于何种原因,上述方法都不适用于intellij:

Compact constructor access level cannot be more restrictive than the record access level (public)

我可以通过使用普通类(允许使用单个包私有构造函数)来避免这个问题,但是我希望更准确地将数据建模为记录。
为什么对记录存在这种限制?今后有没有取消这一限制的计划?

ar7v8xwq

ar7v8xwq1#

为什么对记录存在这种限制
在jep或jls中没有明确的理由来证明这一决定,但我认为这一点可以从jep的摘录中得到暗示:
因为记录在语义上宣称是数据的透明载体。。。
“透明载体”意味着(对我来说)记录被设计成具有最小的抽象边界。限制构造函数的访问意味着(对我来说)一个额外的抽象边界。
此外,我怀疑具有更严格访问修饰符的记录构造函数可能会妨碍或使java未来版本中记录的预期用例复杂化。
不管怎样,我的观点是,如果你想要像这样花哨的东西,你应该声明一个类而不是一个记录。
今后有没有取消这一限制的计划?
我不知道有什么。没有(公开的)公开的java bug或rfe。
实际上,所有与此主题相关的jdk错误都是为了确保java15+规范明确了限制。没有迹象表明限制是意外或疏忽造成的。

相关问题