Lombok 初体验

本贴最后更新于 2297 天前,其中的信息可能已经时移世改

背景

在阅读 sharding-sphere 源代码时,看到其中使用了 Lombok 库。同时,在别的两三个源码中,也看到了这个库的身影。

Lombok 库最大的优点是使用注解来减少重复代码,再也不用写 getter, equals 等代码了。

Lombok 库的官方网站为 projectlombok,其源代码托管在 github 上。

本文来记录一下 Lambok 库的使用。

安装

eclipse

  1. 下载 lombok.jar
  2. 双击 jar 包:会自动找到 eclipse,然后自动安装
  3. 重启 eclipse
  4. 在 eclipse 的 about 页面可以看到 Lombok v1.18.0 "Envious Ferret" is installed. https://projectlombok.org/,说明安装成功

Jetbrains IntelliJ IDEA

  1. Preferences > Plugins
  2. Browse repositories...
  3. 搜索 Lombok Plugin
  4. 点击 Install plugin
  5. 重启 IntelliJ IDEA

第一个例子

pom 依赖

目前,最新稳定为 1.8,引入依赖:

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.0</version>
        </dependency>

类 Getter/Setter

package testLombok;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Book {

    public String name;

    public String ISBN;

    public String pubDate;

    public static void main(String[] args) {
        Book book = new Book();
        book.setName("note");
        book.setISBN("abeffect");
        book.setPubDate("2018-07-21");
        System.out.println("name: " + book.getName());
        System.out.println(book);
    }
}

运行结果

name: note
Book(name=note, ISBN=abeffect, pubDate=2018-07-21)

字段 Getter/Setter

package testLombok;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@ToString
public class Book2 {

    public @Setter @Getter String name;

    public @Setter @Getter String ISBN;

    public @Setter @Getter String pubDate;

    public static void main(String[] args) {
        Book2 book = new Book2();
        book.setName("note");
        book.setISBN("abeffect");
        book.setPubDate("2018-07-21");
        System.out.println("name: " + book.getName());
        System.out.println(book);
    }
}

运行结果

name: note
Book2(name=note, ISBN=abeffect, pubDate=2018-07-21)

Lombok 的特征

常用的

  • @Getter: 可用在类上,或者单个类字段上。
  • @Setter: 可用在类上,或者单个类字段上。
  • @ToString
  • @EqualsAndHashCode

ToString

  • includeFieldNames: 是否包含字段名称
  • exclude: 排除字段
  • callSuper: 输出父类字段,默认为 false

构造函数

  • @AllArgsConstructor: 包含所有字段的构造函数,参数顺序与字段定义顺序一致。如果和 NotNull 注解联用,则会检验是否为空。
  • @NoArgsConstructor: 无参构造函数
  • @RequiredArgsConstructor: 生成包含 final 和 @NotNull 字段的构造方法。

@Data

组合注解: @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode

日志

示例如下:

//@Log
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(Book.class.getName());

//@Log4j
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(Book.class);

//@Log4j2
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(Book.class);

//@Slf4j
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Book.class);

//@CommonsLog
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(Book.class);

//@JBossLog
private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(Book.class);

//@Flogger
private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass();

//@XSlf4j
private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(Book.class);

Builder

bulder 模式构建对象。如上面的示例,可为:

package testLombok;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
@AllArgsConstructor
@RequiredArgsConstructor
@Builder
public class Book {

    public String name;

    public String ISBN;

    public String pubDate;

    public static void main(String[] args) {
        Book book = new Book();
        book.setName("note");
        book.setISBN("abeffect");
        book.setPubDate("2018-07-21");
        System.out.println("name: " + book.getName());
        System.out.println(book);

        Book book2 = Book.builder().name("note").ISBN("abeffect").pubDate("2018-07-21").build();
        System.out.println(book2);
    }
}

结果

name: note
Book(name=note, ISBN=abeffect, pubDate=2018-07-21)
Book(name=note, ISBN=abeffect, pubDate=2018-07-21)

@Cleanup

自动化关闭流,相当于 jdk1.7 种的 try with resource

示例

@Cleanup 
InputStream in = new FileInputStream(args[0]);
@Cleanup 
OutputStream out = new FileOutputStream(args[1]);

默认的清理方法为 close,可以通过 value 来指定不同的清理方法。

类型推导

  • var: 可变变量,相当于普通的变量.
  • val: 只读变量,相当于 final.

@NonNull

变量不能为 null,否则报空指针异常。如

public NonNullExample(@NonNull Person person) {
    this.name = person.getName();
}

对应的为:

public NonNullExample(@NonNull Person person) {
    if (person == null) {
        throw new NullPointerException("person");
    }
    this.name = person.getName();
}

@Value

用在类上,生成含所有参数的构造方法,get 方法,此外还提供了 equals、hashCode、toString 方法。

但是不生成 set 方法。

@SneakyThrows

将异常包装为 RuntimeException,在运行时抛出。如:

    @SneakyThrows(UnsupportedEncodingException.class)
    public String byte2String(byte[] bytes) {
        return new String(bytes, "UTF-8");
    }

@Synchronized

同步执行,基本相当于在方法前加了 synchronized 关键字的效果,实际上是使用的内部对象做的同步。

对于非静态方法,使用 $lock 字段;对于静态方法,使用 $LOCK 字段。

@Getter(lazy=true)

在实际使用到 cached 的时候生成 cached,同时,Lombok 会自动去管理线程安全的问题,不会存在重复赋值的问题。

示例:

    @Getter(lazy = true)
    private final double[] cached = expensive();

    private double[] expensive() {
        double[] result = new double[1000000];
        for (int i = 0; i < result.length; i++) {
            result[i] = Math.asin(i);
        }
        return result;
    }

experimental

@FieldNameConstants

FieldNameConstants 官方文档

import lombok.experimental.FieldNameConstants;
import lombok.AccessLevel;

@FieldNameConstants
public class FieldNameConstantsExample {
    private final String iAmAField;
    @FieldNameConstants(level = AccessLevel.PACKAGE)
    private final int andSoAmI;
}

public class FieldNameConstantsExample {
    public static final String FIELD_I_AM_A_FIELD = "iAmAField";
    static final String FIELD_AND_SO_AM_I = "andSoAmI";

    private final String iAmAField;
    private final int andSoAmI;
}

@Singular

Singular 官方文档

@Delegate

Delegate 官方文档

@Accessors

Accessors 官方文档

@Wither

Wither 官方文档

参考

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3186 引用 • 8212 回帖 • 1 关注

相关帖子

1 回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • wizardforcel

    你都加上 @Builder 了:

    Book b = Book.builder()
        .setName("note")
        .setISBN("abeffect")
        .setPubDate("2018-07-21")
        .bulid();