33

Java 14 引入了记录功能。Record 创建与字段同名的 getter,因此可以编写print(person.name())例如。但是旧的 Java bean 约定规定应该将此方法命名为getName().

在同一个代码库中使用这两种样式看起来不太好。将所有内容迁移到记录是不可能的,因为它们太有限而无法替换所有用例。

是否有任何官方或半官方指南如何在新代码中在 Java 14 之后命名 getter 和 setter?

4

3 回答 3

17

引用JEP 359

向样板宣战不是目标;特别是,使用 JavaBean 命名约定来解决可变类的问题并不是目标。

我的理解是,基于同一个文件,记录transparent holders for shallowly immutable data.

话虽如此:

  1. 记录不是寻找 getter/setter 语法糖的地方,因为它们并不是要取代 JavaBeans。
  2. 我非常同意你的观点,JavaBeans 太冗长了。也许可以实现一个附加功能(称为beans而不是records ) - 与records功能非常相似的行为,但允许可变性。在这种情况下,记录bean不会相互排斥。
  3. 如前所述,记录处于预览模式。让我们看看社区的反馈是什么。

总而言之,恕我直言,它们向前迈进了一步……我编写了这个示例集,您可以在其中看到代码从标准 JavaBeans 减少到 ~15% LOC。

另外,请注意records behave like normal classes: they can be declared top level or nested, they can be generic, they can implement interfaces(来自同一文档)。您实际上可以通过提取包含 getter 的接口来部分模拟 JavaBeans(尽管只有 getter 才有意义)——但这将是很多工作,而不是一个真正干净的解决方案......

所以,根据上面的逻辑,为了解决你的问题,- 我没有看到任何(半)官方的 getter 和 setter 指南,我认为现在没有动机,因为再次记录不是 JavaBeans 的替代品...

于 2020-02-01T03:02:55.250 回答
0

record规范现在是 Java 17 的“最终”规范,不幸的是,这种命名约定差异尚未得到解决。在尝试利用 Records 作为浅持有者类来实现现有域模型的接口部分时,我偶然发现了它。

虽然这不是我想要的那样简洁的解决方案,但 Records 可以有方法,因此您可以将“旧版”getter 添加到您record的 .

public interface Nameable {
   public String getName();
}

public record Person(String name) implements Nameable {
   public String getName() {
      return name;   // or return name();
   }
}

至少这允许客户端代码继续使用久经考验的(超过 20 年的)约定,让我们面对现实吧,它的使用远远超过纯 JavaBeans 上下文中的使用。

你可以说语言设计者没有辜负他们“不对样板宣战”的职责

于 2022-01-08T16:31:16.020 回答
-3

在 Java 记录中,对象字段必须是 private 和 final的。所以只有一种 getter 和一种 setter 是可能的。

在 Java 类中,对象字段可能是私有的或公共的。在后一种类型的字段中,可以简单地通过添加句点和字段名称来获取或设置它们,例如

 Employee emp = new Employee(); // Nullary constructor
 emp.name = "John Schmidt";     // Setter
 . . . 
 . . . 
 if (emp.name != "Buddy")       // Getter
 {
    emp.bonus = 100.00;
 }

Android 应用程序中大量使用非私有字段来节省内存和提取数据的时间。但是没有理由不在 Java 中使用它们,因为这样做是安全的。

现在,如果您从 Java 类中的常用方式更改为记录类型中使用的方式,例如

String name = emp.name();  // New getter convention for private field

您有可能被代码阅读者误解为非私有对象字段的严重风险。

如果您将记录获取器更改为 Java 对象中使用的内容,即

obj.getField()

那么编码审查者就有混淆的风险,并且可能编译器可能会将其视为 Java 对象,具体取决于执行决策标准。

简而言之,它是与普通 Java 类或枚举不同类型的对象。它的访问者明确指出了这种新类型。反正我就是这么看的。也许Java开发委员会的某个人可以进一步启发我们。

于 2020-05-31T19:04:39.590 回答