使用Java 14记录(Records)实现只有final字段的通用(非数据)类

4

对于一个拥有 final 字段的简单类,例如 String(请参见下面的示例)或 Spring 依赖项,使用 Java 14 的记录功能是否是一个好主意,可以使其更加简洁,并可能消除注解处理器,例如 Lombok?

根据描述记录的JEP,“记录具有作为数据的简单、透明的持有者的语义声明”。

显然,仅具有 final 字段的泛型类并不完全是其数据的透明持有者,而在使用记录时,它的 final 变量被公开,这可能是不希望的。但是,在许多情况下,这可能并不是一个主要问题。

因此,这“足够”考虑将其视为这种语言特性的“滥用”吗?还是存在其他不太明显的缺点?

@RequiredArgsConstructor // or an explicit constructor when not using lombok
class AudienceValidator implements OAuth2TokenValidator<Jwt> {
    private final String audience;

    public OAuth2TokenValidatorResult validate(Jwt jwt) {
        // validate
    }
}


record AudienceValidator(String audience) implements OAuth2TokenValidator<Jwt> {

    public OAuth2TokenValidatorResult validate(Jwt jwt) {
        // validate
    }
}
1个回答

11

这取决于既定的语义,但根据我所看到的,这可能是一种滥用。 AudienceValidator 是否仅仅由它的状态组成?它的所有行为是否都源于它的状态(就像 norm() 方法源于一个 Complex 的实部和虚部一样)?

最好的方法是将记录视为带有行为的命名元组。(一个有用的比喻:Java枚举类型相对于C语言枚举类型,就好比记录相对于结构化元组。)但这似乎不是你在这里所做的,因此客户端在API中看到这个类作为记录暴露,却表现出其他行为时,会感到困惑。

你也许会问:“但是,为什么我不能利用这种语言特性使编写这个类更容易呢?” 当然你可以自由选择,但阅读代码比编写代码更重要。故意使用错误的功能只因为它更容易,这是把作者的方便性置于读者之上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接