Java 代码简洁之道 —— Lombok

——乐之者java。相关链接:

https://space.bilibili.com/392539815
http://www.roadjava.com/

Lombok 可以简化 POJO 类的书写,如 getter 、 setter 、tostring 、equals 、hashcode 等。

POJO,简单 Java 对象,不包含业务逻辑,能够控制自己内部 n 个属性访问的 Java 对象。

通过 Maven 引入 Lombok 依赖:

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

使用前的配置

Eclipse

找到 Lombok jar 包所在位置,执行

java -jar lombok-1.18.10.jar

在弹出的窗口中选择 Eclipse 的安装目录即可,并重启 Eclipse 。
其实就是帮你修改了 eclipse.ini 文件,在文件末尾添加了一行内容:

-javaagent:(Lombok jar 包所在目录的绝对路径)

IDEA

  1. 文件 => 设置 => 构建、执行、部署 => 编译器 => 注解处理器
    勾选 启用注解处理 选项:
    image

使用 JSR 269 都需要勾选该选项

  1. 安装 Lombok 的 IDEA 插件
    Lombok 官网可查:
    image
    IDEA 默认已捆绑:
    image

Lombok 提供的注解

@AllArgsConstructor 、@NoArgsConstructor 、@RequiredArgsConstructor

示例:

package org.example;

import lombok.*;

import java.util.Date;

@AllArgsConstructor(access = AccessLevel.PRIVATE) // 设置全参构造函数的访问级别为 private
// @NoArgsConstructor
@RequiredArgsConstructor
public class UserInfo {
    private long id;
    private String name;
    private String phone;
    private Date birthday;
    private String address;

    /**
     * @RequiredArgsConstructor 包含两种属性
     * */
    @NonNull // 1. 当属性被加了 @NonNull ,则该属性会被包含在构造函数中
    private String nonNullProp;
    // 2. final, 定义时初始化或在构造函数中初始化,当加了 final ,则该属性会被包含在构造函数中:
    private final String finalProp;
}

@Getter 、@Setter

示例:

package org.example;

import lombok.*;

import java.util.Date;

@Getter
@Setter
public class UserInfo2 {
    private long id;
    private String name;
    private String phone;
    private Date birthday;

    // NONE 表示不生成 address 的 Getter 、Setter 方法:
    @Getter(value = AccessLevel.NONE)
    @Setter(value = AccessLevel.NONE)
    private String address;

    // 自己写的 Getter 、Setter 方法优先级更高:
    public String getName() {
        return "我自己写的 getName 方法 " + name;
    }
}

@ToString

示例:

package org.example;

import lombok.*;

import java.util.Date;

@AllArgsConstructor
// @ToString
@ToString(
//        of = { "id" }, // 仅包含 id
        exclude = { "name" }, // 排除 name
        callSuper = true // 指定调用父类的 toString + 本类的 toString
)
public class UserInfo3 {
    private long id;
    private String name;
    private String phone;
    private Date birthday;
    private String address;
}

@EqualsAndHashCode

示例:

package org.example;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;

import java.util.Date;

@AllArgsConstructor
// @EqualsAndHashCode
// equals() 和 hashCode() 要保持逻辑上的一致:
@EqualsAndHashCode(of = { "id" }) // 只使用 id 来生成 equals 和 hashCode 方法
public class UserInfo4 {
    private long id;
    private String name;
    private String phone;
    private Date birthday;
    private String address;
}

@Data

package org.example;

import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.Date;

@Data // 相当于 @Getter 、@Setter 、@ToString 、@EqualsAndHashCode(默认选择选择全部属性)的合集,同时还会生成所有以 final 属性作为参数的构造器
@EqualsAndHashCode(of = { "id" }) // 覆写
public class UserInfoData {
    private long id;
    private String name;
    private String phone;
    private Date birthday;
    private String address;
}

@Accessors

示例:

package org.example;

import lombok.Data;
import lombok.experimental.Accessors;

import java.util.Date;

@Data
@Accessors(
//        chain = true, // 链式编程
        fluent = true // fluent = true 即默认 chain = true
) // @Accessors 本身不做任何事情,需要基于 @Data 或 @Getter 、@Setter 使用
public class UserInfoAccessors {
    private long id;
    private String name;
    private String phone;
    private Date birthday;
    private String address;

    public static void main(String[] args) {
        UserInfoAccessors userInfoAccessors = new UserInfoAccessors();

        // chain = true:
        // userInfoAccessors.setId(1L).setName("Zhao").setPhone("12345678900").setBirthday(new Date()).setAddress("中国");
        // System.out.println(userInfoAccessors);

        // fluent = true:
        userInfoAccessors.id(1L).name("Zhao").phone("12345678900").birthday(new Date()).address("中国");
        System.out.println(userInfoAccessors);
        String address = userInfoAccessors.address();
        System.out.println(address);
    }
}

@Slf4j

在运行时,@Slf4j 会在 UserInfoService 这个类中自动生成一个 SLF4J Logger 。这个简单的注解和在类中通过如下代码显式声明的效果是一样的:

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UserInfoService.class);

引入 logback :

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>X.X.X</version>
</dependency>

示例:

package org.example;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@Slf4j // 专门针对项目里面使用的是 slf4j
public class UserInfoService {
//    private static final Logger LOGGER = LoggerFactory.getLogger(UserInfoService.class);
    public List<UserInfo> getAll() {
//        LOGGER.info("进入 getAll 方法");
        log.info("进入 getAll 方法"); // 注意 log 的 l 是小写的
        return new ArrayList<>();
    }

    public static void main(String[] args) {
        UserInfoService userInfoService = new UserInfoService();
        userInfoService.getAll();
    }
}

@Log 、@Log4j 、@Log4j2 ...

posted @ 2023-03-21 13:20  HopeLive  阅读(96)  评论(0)    收藏  举报