【问题标题】:Java 15 - records with different return type for getter [duplicate]Java 15-getter 具有不同返回类型的记录 [重复]
【发布时间】:2020-11-03 23:01:30
【问题描述】:

是否可以在 java 15 中实现类似的东西?

record Something(
        SomeId id,
        MyProp myProp,
        MaybeProp maybeProp
){
    public Something(SomeId id, MyProp myProp){
        this(id, myProp, null);
    }

    public Optional<MaybeProp> maybeProp(){ //problematic line
        return Optional.ofNullable(maybeProp);
    }
}

这里我得到了异常

(return type of accessor method maybeProp() must match the type of record component maybeProp)

所以 - 我明白问题所在;但是还有其他解决方案吗?如何在记录中有可选成员,我不需要使用 Optional.of() 进行初始化?

【问题讨论】:

  • 只是澄清一下-您希望记录字段作为参考,null 表示“不存在”,但您希望在用户请求值时将其返回为Optional?如果这是您的问题,那么答案是不可能隐藏或更改每个字段的自动生成的读取访问器的返回类型。您将需要一个具有不同名称的附加访问器,该访问器使用ofNullable返回Optional
  • 完全正确。这会起作用,只是有点难看。我想我还必须以某种方式禁用 maybeProp 以便它不会被调用。
  • 我将添加一个不同的建议作为答案
  • 将 MaybeProp 的类型更改为 Optional 并在构造函数而不是 getter 中进行包装怎么样?
  • 记录的基本权衡是:您已经放弃了将 API 与表示分离的能力;用于构造和访问的 API 直接来自状态描述。所以不行。如果一个组件的类型是T,那么它对应的访问器和规范构造函数参数的类型也将是T。 (但你可以有额外的构造函数。)

标签: java java-record java-15


【解决方案1】:

您不能隐藏或更改记录字段自动生成的读取访问器的返回类型。

实现您正在寻找的一种方法是让记录实现一个接口,然后使用该接口而不是记录类型:

interface PossibleSomething {
    Optional<Something> maybeSomething();
}

record SomethingRecord(Something something) implements PossibleSomething {
    public Optional<Something> maybeSomething() {
        return Optional.ofNullable(something);
    }
}

// user code:
PossibleSomething mySomething = new SomethingRecord(something);
mySomething.maybeSomething().ifPresent(...)

通过在调用代码中使用PossibleSomething,您明确声明您不需要直接访问该字段,而只能通过接口的访问器访问它。

作为设计理念,记录明确旨在(根据JEP)支持将数据建模为数据。换句话说,他们的用例是当您拥有要存储的直接不可变数据并让用户直接访问时。这就是他们不支持更改访问器的原因:这不是记录的用途。我在上面展示的模式(即实现隐藏访问接口的记录)是一种隐藏使用记录作为实现细节并控制对字段的访问的方法。

【讨论】:

  • 谢谢。我总是可以使用这个类。只是想知道记录是否是一种选择。
  • 和 OP 发布的另一个问题,即试图隐藏实际访问器的问题仍然存在于这种模式中。
  • @Naman 不确定您的意思。因为引用被分配给具有接口类型的变量,所以没有访问数据的方法。
  • @sprinter 我猜他是说如果你像SomethingRecord mySomething 一样使用它(你可以),你仍然会拥有mySomething.something() 访问器。
  • @BojanVukasovic 正如我在回答的第一句话中提到的那样,不可能隐藏记录的公共访问者。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-09
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
相关资源
最近更新 更多