【问题标题】:Java + Lombok - populate a field at .build() timeJava + Lombok - 在 .build() 时间填充一个字段
【发布时间】:2023-01-10 23:17:00
【问题描述】:

这个想法是在.build()时间填充summary

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@Data
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class Book
{
    protected String title;
    protected String author;
    protected String description;
}

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.SuperBuilder;

@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class BookSummary extends Book
{
    public String summary;

    public BookSummary(BookSummaryBuilder<?, ?> b)
    {
       super(b);
       this.summary = getTitle() + getAuthor() + getDescription();
    }  
}

一切正常,但我想知道是否有更简单/更优雅的方法来做同样的事情而不需要创建这个构造函数

更新

我不能简单地覆盖 summary get 方法,因为一些将接收此对象作为参数的 API 不使用访问器从字段中检索值。

例如:

public class BookSummary extends Book
{
    @Builder.Default
    public String summary = "xxxxxxxxxxxxxxx";

    public String getSummary()
    {
        return getTitle() + getAuthor() + getDescription();
    }
}

BookSummary bookSummary = BookSummary.builder()
            .title("Java forever")
            .author("John John")
            .description("bla-bla-bla-bla")
            .build();

String json = new GsonBuilder().create().toJson(bookSummary)

JSON:

{
    "summary":"xxxxxxxxxxxxxxx",
    "title":"Java forever",
    "author":"John John",
    "description":"bla-bla-bla-bla"
}

【问题讨论】:

  • 没有那个构造函数它工作正常,你测试了吗?
  • 创建getSummary方法并在那里,this.summary = getTitle() + getAuthor() + getDescription();
  • @YoucefLAIDANI - 在没有构造函数的情况下将在哪个时刻填充摘要?
  • @AbhijitSarkar - 我更新了帖子以解释为什么创建 getSummary 在我的情况下不起作用

标签: java lombok


【解决方案1】:

没有更简单的方法可以直接做到这一点,但是,这种设计是可疑的。鉴于有一个单独的字段,现在可能会出现“无效”状态 - 字段不一致。例如,summary 只包含“Hello world”,而不是您实际希望它包含的内容。

更好的解决方案是根本没有字段,只写一个 getter:

public String getSummary() {
  return getTitle() + " " + getAuthor() + " " + getDescription();
}

或者,如果这个类的设计(你的问题在这个主题上不清楚)是这样的,你能够添加一个摘要,但如果你不这样做,你会得到标题+作者+描述,仍然,写 getter,只是,稍微不同的做法:使用 null"" 作为标记:

public String getSummary() {
  return summary != null ? summary :
    (getTitle() + " " + getAuthor() + " " getDescription());
}

这两种策略都避免了将字段显式设置为构建过程的一部分的需要。 Lombok 确实有 @Builder.Default 机制,但是这个机制不能用于引用在构建过程中设置的任何东西(即你可以设置为默认的 'Hello world',或者甚至 "" + System.currentTimeMillis() 如果你愿意,任何 java 表达式都可以,但是您不能将调用者设置的标题、作者或描述引用到构建器,因此您不能使用它来将 summary 字段“默认”为您想要的内容。

【讨论】:

  • 我更新了帖子以解释为什么创建 getSummary() 在我的情况下不起作用。该字段永远不会明确设置,仅由构建器在构建时设置。
猜你喜欢
  • 2014-07-08
  • 2014-06-25
  • 1970-01-01
  • 2011-02-25
  • 1970-01-01
  • 2011-08-03
  • 2021-10-05
  • 1970-01-01
相关资源
最近更新 更多