Using Lombok’s @Accessors Annotation – 使用Lombok’的@Accessors注释

最后修改: 2019年 11月 11日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

It’s pretty typical to have get and set methods in our domain objects, but there are other ways that we may find more expressive.

在我们的领域对象中拥有get set 方法是非常典型的,但是还有其他的方法,我们可能会发现它们更具有表现力。

In this tutorial, we’ll learn about Project Lombok‘s @Accessors annotation and its support for fluent, chained, and custom accessors.

在本教程中,我们将了解Project Lombok@Accessors 注解及其对流畅、链式和自定义访问器的支持。

Before continuing, though, our IDE will need Lombok installed.

不过在继续之前,我们的IDE将需要安装Lombok

2. Standard Accessors

2.标准访问器

Before we look at the @Accessors annotation, let’s review how Lombok treats the @Getter and @Setter annotations by default.

在我们查看@Accessors 注解之前,让我们回顾一下Lombok如何默认处理@Getter @Setter 注解。

First, let’s create our class:

首先,让我们创建我们的类。

@Getter
@Setter
public class StandardAccount {
    private String name;
    private BigDecimal balance;
}

And now let’s create a test case. We can see in our test that Lombok has added typical getter and setter methods:

现在让我们创建一个测试案例。我们可以看到在我们的测试中,Lombok已经添加了典型的getter和setter方法。

@Test
public void givenStandardAccount_thenUseStandardAccessors() {
    StandardAccount account = new StandardAccount();
    account.setName("Basic Accessors");
    account.setBalance(BigDecimal.TEN);

    assertEquals("Basic Accessors", account.getName());
    assertEquals(BigDecimal.TEN, account.getBalance()); 
}

We’ll see how this test case changes as we look at @Accessor‘s options.

当我们查看@Accessor的选项时,我们将看到这个测试案例的变化。

3. Fluent Accessors

3.流利的访问器

Let’s begin with the fluent option:

让我们从fluent选项开始。

@Accessors(fluent = true)

The fluent option gives us accessors that don’t have a get or set prefix.

fluent选项为我们提供了没有getset前缀的访问器。

We’ll take a look at the chain option in a moment, but since it’s enabled by default, let’s disable it explicitly for now:

我们一会儿会看一下选项,但由于它是默认启用的,我们现在先明确地禁用它。

@Accessors(fluent = true, chain = false)
@Getter
@Setter
public class FluentAccount {
    private String name;
    private BigDecimal balance;
}

Now, our test still behaves the same, but we’ve changed the way we access and mutate state:

现在,我们的测试仍然表现相同,但我们改变了访问和变异状态的方式。

@Test
public void givenFluentAccount_thenUseFluentAccessors() {
    FluentAccount account = new FluentAccount();
    account.name("Fluent Account");
    account.balance(BigDecimal.TEN);

    assertEquals("Fluent Account", account.name()); 
    assertEquals(BigDecimal.TEN, account.balance());
}

Notice how the get and set prefixes have disappeared.

注意到get和set的前缀已经消失了。

4. Chained Accessors

4.链式访问器

Now let’s take a look at the chain option:

现在让我们来看看选项。

@Accessors(chain = true)

The chain option gives us setters that return thisAgain note that it defaults to true, but we’ll set it explicitly for clarity.

选项给了我们返回this的设置器。再次注意,它的默认值是true,但为了清晰起见,我们将明确地设置它。

This means we can chain multiple set operations together in one statement.

这意味着我们可以在一条语句中把多个set操作连在一起。

Let’s build on our fluent accessors and change the chain option to true:

让我们在fluent访问器的基础上,将chain选项改为true

@Accessors(fluent = true, chain = true)
@Getter 
@Setter 
public class ChainedFluentAccount { 
    private String name; 
    private BigDecimal balance;
}

We get the same effect if we leave out chain and just specify:

如果我们撇开chain而只指定,我们会得到同样的效果。

@Accessors(fluent = true)

And now let’s see how this affects our test case:

现在让我们看看这对我们的测试案例有何影响。

@Test
public void givenChainedFluentAccount_thenUseChainedFluentAccessors() {
    ChainedFluentAccount account = new ChainedFluentAccount()
      .name("Fluent Account")
      .balance(BigDecimal.TEN);

    assertEquals("Fluent Account", account.name()); 
    assertEquals(BigDecimal.TEN, account.balance());
}

Notice how the new statement becomes longer with the setters chained together, removing some boilerplate.

注意到new语句如何在setters链在一起的情况下变得更长,删除一些模板。

This, of course, is how Lombok’s @Builder makes use of chained fluent accessors.

当然,这就是Lombok的@Builder如何利用ed流畅访问器。

5. Prefix Accessors

5.前缀访问器

And finally, at times our fields may have a different naming convention than we’d like to expose via getters and setters.

最后,有时我们的字段可能有一个不同的命名规则,而不是我们想通过getters和setters来公开的。

Let’s consider the following class that uses Hungarian Notation for its fields:

让我们考虑一下下面的类,它的字段使用了匈牙利语符号。

public class PrefixedAccount { 
    private String sName; 
    private BigDecimal bdBalance; 
}

If we were to expose this with @Getter and @Setter, we’d get methods like getSName, which isn’t quite as readable.

如果我们用@Getter@Setter来暴露这一点,我们会得到像getSName这样的方法,这就不太容易阅读了。

The prefix option allows us to tell Lombok which prefixes to ignore:

prefix选项允许我们告诉Lombok要忽略哪些前缀。

@Accessors(prefix = {"s", "bd"})
@Getter
@Setter
public class PrefixedAccount {
    private String sName;
    private BigDecimal bdBalance;
}

So, let’s see how that affects our test case:

所以,让我们看看这对我们的测试案例有何影响。

@Test
public void givenPrefixedAccount_thenRemovePrefixFromAccessors() {
    PrefixedAccount account = new PrefixedAccount();
    account.setName("Prefixed Fields");
    account.setBalance(BigDecimal.TEN);

    assertEquals("Prefixed Fields", account.getName()); 
    assertEquals(BigDecimal.TEN, account.getBalance());
}

Notice how the accessors for our sName field (setName, getName) omit the leading s and the accessors for bdBalance omit the leading bd.

注意我们的sName字段的访问器(setName,getName)如何省略了前面的s,以及bdBalance的访问器省略了前面的bd

However, Lombok only applies prefixes when a prefix is followed by something other than a lowercase letter.

然而,Lombok 只有当前缀后面是小写字母以外的东西时才适用前缀。

This makes sure that if we have a field that isn’t using Hungarian Notation, such as state, but starts with one of our prefixes, s, we don’t end up with getTate()!

这确保了如果我们有一个没有使用匈牙利符号的字段,例如state,,但以我们的一个前缀s开始,我们就不会以getTate()!结束。

Lastly, let’s say we want to use underscores in our notation but also want to follow it with a lowercase letter.

最后,假设我们想在我们的符号中使用下划线,但也想在它后面加上一个小写字母。

Let’s add a field s_notes with prefix s_:

让我们添加一个字段s_notes,前缀为s_:

@Accessors(prefix = "s_")
private String s_notes;

Following the lowercase letter rule we’d get methods like getS_Notes(), so Lombok also applies prefixes when a prefix itself ends in something that isn’t a letter.

按照小写字母规则,我们会得到像getS_Notes()这样的方法,所以当前缀本身以不是字母的东西结尾时,Lombok也适用前缀

6. Configuration Properties

6.配置属性

We can set a project- or directory-wide default for our favorite combination of settings by adding configuration properties to a lombok.config file:

我们可以通过在lombok.config文件中添加配置属性,为我们喜欢的设置组合设置一个项目或目录范围内的默认值。

lombok.accessors.chain=true
lombok.accessors.fluent=true

See the Lombok Feature Configuration Guide for further details.

请参阅Lombok 功能配置指南以了解更多细节。

7. Conclusion

7.结语

In this article, we used the fluent, chain, and prefix options of Lombok’s @Accessors annotation in various combinations to see how it affected the generated code.

在这篇文章中,我们使用了Lombok的@Accessors注解的fluent, chain, prefix选项的不同组合,看看它对生成的代码有何影响。

To learn more, be sure to take a look at the Lombok Accessors JavaDoc and Experimental Feature Guide.

要了解更多信息,请务必查看Lombok Accessors JavaDocExperimental Feature Guide

As usual, the source for this article is available over on GitHub.

像往常一样,本文的源代码可以在GitHub上找到