Project lombok генерирует не только геттеры и сеттеры, но и конструкторы и свойства полей класса.
Модификаторы полей.
В первую очередь избавимся от вечноповторяющихся private и final. Аннотация @FieldDefaults, применённая на класс, позволяет задать всем поля класса уровень доступа по умолчанию или сделать все поля final по умолчанию. В случае, если требуется исключение, можно использовать аннотацию @NonFinal , чтобы убрать final с конкретного поля. Аннотация @PackagePrivate аналогичным образом работает для уровня доступа — значение из @FieldDefaults игнорируется.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/**
* Sample user entity
*/
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@NoArgsConstructor(force = true)
@RequiredArgsConstructor
public class User {
/**
* Id.
*/
@Getter
private Long id;
/**
* User name.
*/
@Getter
@NonNull
private String name;
/**
* Some value, that you can set.
*/
@Getter
@Setter
@NonFinal
BigDecimal value;
}
|
Конструкторы
Аннотация @NoArgsConstructor создаёт конструктор по умолчанию. В случае, если в классе есть final поля, такой конструктор сгенерирован не будет. Но, если очень сильно попросить, передав в @NoArgsConstructor параметр force = true, то конструктор будет сгенерирован, а final поля будут инициализированы пустыми значениями. В том числе пустые значения будут присвоены полям с аннотацией @NonNull.
@RequiredArgsConstructor генерирует конструктор, принимающий значения для каждого final поля или поля с аннотацией @NonNull Аргументы конструктора будут сгенерированы в том порядке, в котором поля перечислены в классе. Для @NonNull полей конструктор так же будет проверять, чтобы в него не передали значение null.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@Test
public void testConstructor() {
User testedObject = new User(1L, "TEST");
assertThat(testedObject.getId(), is(1L));
assertThat(testedObject.getName(), is("TEST"));
}
@Test(expected = NullPointerException.class)
public void testNullName() {
new User(1L, null);
}
@Test
public void testDefaultConstructor() {
User testedObject = new User();
assertNull(testedObject.getId());
assertNull(testedObject.getName());
assertNull(testedObject.getValue());
}
|
Все три аннотации принимают аргумент staticName, который позволяет создать статическую обёртку вокруг конструктора, с заданным именем и использовать её:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/**
* Sample account entity.
*/
@FieldDefaults(level = AccessLevel.PRIVATE)
@AllArgsConstructor(staticName = "create")
public class Account {
/**
* Id.
*/
@Getter
@Setter
Long id;
/**
* Account owner.
*/
@NonNull
@Getter
@Setter
User owner;
/**
* Account's value.
*/
@Getter
@Setter
BigDecimal amount;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
public class AccountTest {
@Test
public void testChainedSetters() {
User user = new User(1L, "TEST");
Account testedObject = Account.create(1L, user, BigDecimal.ONE);
assertThat(testedObject.getId(), is(1L));
assertThat(testedObject.getOwner(), is(user));
assertThat(testedObject.getAmount(), is(BigDecimal.ONE));
}
}
|
Код примера доступен на github.