Lombok 简化冗余代码

Lombok是一个比较神奇的组件,它通过添加了一系列注解,能够简化掉Java代码中让我们不胜其烦的getXX()setXX()equals()hashCode()等代码,对于提升开发效率有很大帮助。Lombok会在编译阶段生效,我们加上这些注解后,编译生成的字节码和手写是一样的。

Lombok项目基于MIT协议开源。项目地址:https://projectlombok.org/

Lombok的优点和缺点

使用Lombok的优点就是极大的简化了Java这门古老的语言中最最冗余的一部分内容,提升了开发效率。但是相应的缺点则是对开发人员要求更高了,Lombok引入了额外的学习内容,与此同时也引入了一些坑,使用者需要有较强的看文档、解决问题的能力。因此,Lombok尤其适合个人开发者使用,也非常适合小型并且队员综合素质较高,有极客精神的敏捷团队使用。对于水平参差不齐,人员构成复杂的团队,建议不要使用,以免引入不必要的麻烦。

安装和使用Lombok

编写如下代码引入Maven依赖,这里我们使用的是1.16.22,实际开发中使用当前最新版本即可,此外SpringBoot官方也维护了兼容的Lombok版本号使得我们不必手动指定。

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.16.22</version>
  <scope>provided</scope>
</dependency>

在Eclipse集成开发环境中,安装Lombok插件的方式比较特殊,插件仓库中并没有相关的插件,我们需要下载Lombok对应的Jar包:https://projectlombok.org/download,然后将该Jar包放到Eclipse安装的根目录中,最后修改eclipse.ini加入以下配置。

-javaagent:lombok.jar

注:Eclipse的Lombok插件安装方式比较特殊的原因也很搞笑,据说作者没有搞明白Eclipse插件如何上传或是如何搭建插件仓库(P2确实是个让人血压升高的东西)。以上插件安装方法仅供参考,随着时间推移可能发生改变。

Lombok语法糖

这部分内容可以参考Lombok文档:https://projectlombok.org/features/all

这里只介绍几个最常用的注解。

@Getter,@Setter

该注解能够自动生成Getter/Setter方法。

public class User {
    private @Getter @Setter String username;
    private String password;
}

@ToString

该注解能够自动生成一个实体类的toString()方法。

@ToString
public class User {
    private String username;
    private String password;
}

可用属性:

  • exclude:指定排除字段,一般用于避免循环引用导致栈溢出
  • callSuper:指定是否调用父类的toString()方法

@EqualsAndHashCode

该注解能够自动生成一个实体类的equals()hashCode()canEqual()

canEqual()是Lombok新增的一个方法,据说是用于代理类和基类的比较,这个非常罕见,不太清楚。

@EqualsAndHashCode
public class User {
    private String username;
    private String password;
}

可用属性基本同@ToString

@NoArgsConstructor,@RequiredArgsConstructor,@AllArgsConstructor

该注解能够自动生成一些构造方法。

  • @NoArgsConstructor:生成一个无参数构造函数
  • @RequiredArgsConstructor:为类中final修饰或@NonNull注解修饰的字段生成构造函数
  • @AllArgsConstructor:生成一个带有全部参数的构造函数
@AllArgsConstructor
public class User {
    private String username;
    private String password;
}

@Data

自动生成无参构造函数,生成各个字段的Getter/Setter方法,生成equals()canEqual()hashCode()方法,生成toString()方法。非常建议在实体类上使用,能大幅优化代码的可读性。不过也要注意,直接使用@Data就无法精确控制排除字段等内容了。

@Data
public class User {
    private String username;
    private String password;
}

@Builder

该注解能够为一个类自动生成Builder构造器。

@Builder
@Data
public class User {
    private String username;
    private String password;
}

调用Builder构造器的例子代码如下。

public class Main {
    public static void main(String[] args) {
        User user = User
                .builder()
                .username("tom")
                .password("123456")
                .build();
        System.out.println(user);
    }
}

@nonNull

该注解能够为方法指定必须参数,如果该参数为null,将抛出异常。

public class Main {
    public static void main(String[] args) {
        foo(null);
    }

    public static void foo(@NonNull String str) {
        System.out.println(str);
    }
}

上述代码运行时会抛出类似如下的异常。

Exception in thread "main" java.lang.NullPointerException: str
    at com.gacfox.demo.Main.foo(Main.java:16)
    at com.gacfox.demo.Main.main(Main.java:13)

@Slf4j

我们使用SLF4J日志框架的时候,一般要在各个类上写Logger logger = LoggerFactory.getLogger(<类名>.class);来获取日志输出需要的工具类,这种写法比较冗余。@Slf4j注解能够自动帮我们注入一个静态字段log,我们可以直接引用。

@Slf4j
public class Main {
    public static void main(String[] args) {
        log.debug("test log");
    }
}

注意:你需要先配置slf4j和一个日志实现库,日志要通过slf4jAPI调用,其他方式不建议使用。

@Cleanup

该注解能够自动生成调用资源对象close方法的代码。强烈不建议使用该注解,资源泄漏是开发中必须要着重注意的一个点,它引起的错误不容易重现和调试。使用Lombok的@Cleanup,我们可能稍不注意就会出此类严重Bug,此外JDK7引入了TryWithResource语法,完全可以代替Lombok的@Cleanup注解。

public class Main {
    public static void main(String[] args) {
        try {
            @Cleanup InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("logback.xml");
            @Cleanup InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            @Cleanup BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String s = bufferedReader.readLine();
            System.out.println(s);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap