Post Java-14 getter/setter 命名约定

Post Java-14 getter/setter naming convention

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

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

有没有关于如何在新代码中在 Java 14 之后命名 getters 和 setter 的官方或半官方指南?

引自JEP 359

It is not a goal to declare "war on boilerplate"; in particular, it is not a goal to address the problems of mutable classes using the JavaBean naming conventions.

根据同一份文件,我的理解是 条记录transparent holders for shallowly immutable data

也就是说:

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

总而言之,恕我直言,它们向前迈进了一步...我写了 this example 集,您可以在其中看到标准 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...

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

在 Java classes 中,对象字段可能是私有的或 public。 在后一种类型的字段中,只需添加句点和字段名称即可获取或设置它们,例如

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

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

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

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

你有被代码读者混淆的严重风险,他们可能会将其误解为非私有对象字段。

并且如果您将记录 getter 更改为 Java 对象中使用的内容,即

obj.getField()

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

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

record 规范现在是 "final" as of Java 17,不幸的是,这个命名约定差异没有得到解决。我在尝试利用 Records as shallow holder 类 来实现现有域模型的接口部分时偶然发现了它。

虽然这不是我想要的完美解决方案,但 Records 可以有方法,因此您可以向 record 添加“遗留”吸气剂,如下所示(人为但简单)例如。

public interface Nameable {
   public String getName();
}

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

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

您可以说语言设计者没有辜负他们“不在样板文件上声明 war”的职权范围