#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);