Lombok toBuilder() 方法是否创建字段的深层副本

问题描述 投票:0回答:4

我在对象实例上使用

toBuilder()
来创建构建器实例,然后使用构建方法来创建新实例。原始对象有一个列表,新对象是否引用相同列表或其副本?

@Getter
@Setter
@AllArgsConstructor
public class Library {

    private List<Book> books;

    @Builder(toBuilder=true)
    public Library(final List<Book> books){
         this.books = books;
    }

}

Library lib2  = lib1.toBuilder().build();

lib2 书籍会引用与 lib1 书籍相同的列表吗?

java lombok
4个回答
38
投票

是的,

@Builder(toBuilder=true)
注释不会执行对象的深层复制,仅复制字段的引用。

List<Book> books = new ArrayList<>();
Library one = new Library(books);
Library two = one.toBuilder().build();
System.out.println(one.getBooks() == two.getBooks()); // true, same reference

1
投票

实际上你可以做的是使用其他映射工具从现有对象创建一个新对象。

例如

com.fasterxml.jackson.databind.ObjectMapper

    @AllArgsConstructor
    public static class Book
    {
        private String title;
    }

    @NoArgsConstructor
    @AllArgsConstructor
    @Getter
    public static class Library
    {
        private List<Book> books;
    }

    ObjectMapper objectMapper = new ObjectMapper(); //it's configurable
    objectMapper.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
    objectMapper.configure( SerializationFeature.FAIL_ON_EMPTY_BEANS, false );

    List<Book> books = new ArrayList<>();
    Library one = new Library( books );

    Library two = objectMapper.convertValue( one, Library.class );
    System.out.println( one.getBooks() == two.getBooks() ); // false, different refs

它可以轻松地包装在一些实用方法中,以便在整个项目中使用,例如

ConvertUtils.clone(rollingStones, Band.class)


0
投票

您可以通过一个简单的技巧手动制作集合的副本:

    List<Book> books = new ArrayList<>();
    Library one = new Library(books);
    Library two = one.toBuilder()
        .books(new ArrayList<>(one.getBooks))
        .build();
    System.out.println(one.getBooks() == two.getBooks()); // false, different refs

0
投票

我通过

@Builder.ObtainVia

解决了这个问题
@Builder.Default @Builder.ObtainVia(method = "copyTags")
private Set<TranslationTag> tags = new HashSet<>();

Set<TranslationTag> copyTags() {
    return new HashSet<>(tags);
}
© www.soinside.com 2019 - 2024. All rights reserved.