Как добавить, используя единственный атрибут в ломбоке

#java #lombok

Вопрос:

Как добавить @Singular атрибут using в ломбоке

 Foo foo = ..;
FooActivity fa = ..;

foo.fooActivity(fa); // this fails - compilation error

@Builder    
class Foo {
    @Singular("fooActivity")
    private List<FooActivity> fooActivities;
}
 

Ответ №1:

Вы пробовали что-то подобное?

 Foo myFoo = Foo.builder()
.fooActivity(new FooActivity())
.fooActivity(new FooActivity())
.build();
 

Комментарии:

1. myFoo уже там и не через строителя. Можно ли тогда добавить к нему шаблон конструктора

2. Нет, шаблон компоновщика недоступен для экземпляра Foo, который уже был создан. Я подозреваю, что вам придется извлекать список с помощью обычного геттера и добавлять элементы в список. В качестве альтернативы создайте и заполните список действий и установите его в экземпляре Foo с помощью метода setter.

Ответ №2:

@Singular должен использоваться вместе с @Builder аннотацией. Таким образом, в этом случае fooActivity метод добавления элемента в список создается в FooBuilder классе, сгенерированном ломбоком, и он НЕ является его частью Foo . Следовательно, вы не можете получить доступ fooActivity с помощью Foo объекта.

Как это решить? (С этим подходом есть проблема, о которой я упоминал в конце.)

Вы можете решить эту toBuilder проблему, установив значение true для @Builder аннотации. Это приведет к созданию метода, Foo который вернет объект builder, который вы можете использовать для вызова fooActivity .

 @Builder(toBuilder = true)
public class Foo {
    @Singular("fooActivity")
    private List<FooActivity> acts;
}

// To invoke
foo = foo.toBuilder().fooActivity(fa).build();
 

Проблема с вышеуказанным подходом

toBuilder() будет сгенерирован конструктор, использующий значения в foo , и build будет сгенерирован НОВЫЙ объект. Поэтому вам нужно быть осторожным с этим, потому что исходный объект foo не обновляется с использованием этого подхода.


Второй подход (Не рекомендуется)

Используйте экспериментальную функцию @Delegate . Вот что говорится на сайте ломбока об этой функции:

В настоящее время мы считаем, что эта функция не выйдет из экспериментального статуса в ближайшее время, и поддержка этой функции может быть прекращена, если будущие версии javac или ecj затруднят дальнейшее поддержание этой функции.

Это также может вызвать проблемы, если в вашем классе несколько коллекций.

 @Builder
public class Foo {
    @Delegate
    @Builder.Default
    private List<FooActivity> acts = new ArrayList<>(); // make sure you do this while using @Delegate    
}
 

Чтобы призвать

 foo.add(fa);