我在对象实例上使用toBuilder()
来创建构建器实例,然后使用build方法来创建新实例。原始对象有一个列表,新对象是否引用了相同列表或副本?
@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书籍引用相同的列表吗?
答案 0 :(得分:1)
是的,@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 :(得分:1)
您可以使用一个简单的技巧手动制作收藏集的副本:
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
答案 2 :(得分:0)
实际上您可以做的是使用其他映射工具从现有对象创建一个新对象。
例如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)