生产力工具 ~ Lombok。

生产力工具 ~ Lombok。



Lombok ~ what。

https://projectlombok.org/

Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.
Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.

消除工作中大量重复的、毫无技术含量的 get(); 、 set(); 方法。



原理。

JSR 269 插件化注解处理 API ~ Pluggable Annotation Processing API。

https://jcp.org/en/jsr/detail?id=269

jdk 6 提供的特性。在 javac 编译期利用注解搞事情。

@Retention(RetentionPolicy.SOURCE)

在这里插入图片描述



安装。

使用。
  • javac。
  • 拷贝 lombok.jar 到类路径。
  • javac -cp lombok.jar …


  • Maven。

pom 依赖。

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
    <scope>provided</scope>
</dependency>



IDEA 中使用。

IntelliJ IDEA
The Jetbrains IntelliJ IDEA editor is compatible with lombok.
~
Add the Lombok IntelliJ plugin to add lombok support for IntelliJ:
~
Go to File > Settings > Plugins
Click on Browse repositories…
Search for Lombok Plugin
Click on Install plugin
Restart IntelliJ IDEA
You can also check out Setting up Lombok with Eclipse and IntelliJ, a blog article on baeldung.

在这里插入图片描述

  • 使用了 @Data 注解。前后对比。

在这里插入图片描述

在这里插入图片描述

注:安装插件是为了 IDEA 的友好提示。如果不安装插件,IDEA 智能提示代码会报红,但仍可以编译运行。



常用注解。

用在类声明上 ~ @Data。
也可以在类成员上单独使用。
package com.geek.lombok;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

//@Data
public class User {

    @Getter(AccessLevel.PROTECTED)
    @Setter
    private Integer id;
    private String userName;
    private String password;
    private String phone;
    private String email;

}

查看 .class 文件。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.geek.lombok;

public class User {
    private Integer id;
    private String userName;
    private String password;
    private String phone;
    private String email;

    public User() {
    }

    protected Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

}

还可以在类声明上使用 @Getter 和 @Setter。
类声明上使用了 @Data,单个成员变量排除使用 ~ @Getter(AccessLevel.NONE)。

@Getter(AccessLevel.NONE)
private String phone;

在这里插入图片描述



注意。
  • static 的成员变量不会有 setter and getter。
  • final 类型只生成 get();。


@ToString
  • Java 中,如果不重写 toString(); 方法,则使用继承自 Object 类的 toString(); 方法。此时如果 System.out.println(user);,控制台会打印出这个对象的内存地址值。

com.geek.lombok.User@74a14482

  • 重写了 toString(); 方法,System.out.println(user); 就会打印出这个对象的属性值。
    public String toString() {
        return "User(id=" + this.getId() + ", username=" + this.getUsername() + ", password=" + this.getPassword() + ", phone=" + this.getPhone() + ", email=" + this.getEmail() + ")";

User(id=1, username=Geek, password=null, phone=null, email=liyifan@lyfGeek.club)

@ToString(exclode = {“”, “”}) 参数可以指定排除的字段。

@ToString(exclude = {“phone”})

@ToString(of = {“”, “”}) 参数可以指定输出字段。


@EqualsAndHashCode。

会生成 equals(); canEqual(); 和 hashCode() 三个方法。

用于判定两个对象是否相等,可以通过重写 equals(); 方法修改判定标准。(eg. 只要 id 和 username 两者相等,我们就认为这两个对象相同)。如果不重写,就必须两个对象的属性全部相同,并且地址值也相同。
~
eg. 使用 @EqualsAndHashCode(exclude = “password”) ——> 如果 id 和 name 相同,我们就认为这两个对象相同。

canEqual();
protected boolean canEqual(Object other) {
return other instanceof User;
}
// 判断对象是不是某个类的实例。


    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof User)) {
            return false;
        } else {
            User other = (User)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                label47: {
                    Object this$id = this.getId();
                    Object other$id = other.getId();
                    if (this$id == null) {
                        if (other$id == null) {
                            break label47;
                        }
                    } else if (this$id.equals(other$id)) {
                        break label47;
                    }

                    return false;
                }

                Object this$username = this.getUsername();
                Object other$username = other.getUsername();
                if (this$username == null) {
                    if (other$username != null) {
                        return false;
                    }
                } else if (!this$username.equals(other$username)) {
                    return false;
                }

                Object this$password = this.getPassword();
                Object other$password = other.getPassword();
                if (this$password == null) {
                    if (other$password != null) {
                        return false;
                    }
                } else if (!this$password.equals(other$password)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof User;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $id = this.getId();
        int result = result * 59 + ($id == null ? 43 : $id.hashCode());
        Object $username = this.getUsername();
        result = result * 59 + ($username == null ? 43 : $username.hashCode());
        Object $password = this.getPassword();
        result = result * 59 + ($password == null ? 43 : $password.hashCode());
        return result;
    }


@NonNull。

    public void test(@NonNull String s) {
        System.out.println(s);
    }

如果传入 null 参数。会报异常。

user.test(null);
Exception in thread “main” java.lang.NullPointerException: s is marked non-null but is null

看看编译后的代码。

    public void test(@NonNull String s) {
        if (s == null) {
            throw new NullPointerException("s is marked non-null but is null");
        } else {
            System.out.println(s);
        }
    }


Constructor。

@NoArgsConstructor
@RequiredArgsConstructor
  • @RequiredArgsConstructor 会默认为 final 类型的成员变量(并且没有赋初始值)和 @NonNull 注解的成员变量生成构造方法。
@Getter
@Setter
@RequiredArgsConstructor
public class User {

    //    @Getter(AccessLevel.PROTECTED)
//    @Setter
    final int id2;
    @NonNull
    private Integer id;
    private String username;
    private String password;
}
    public User(int id2, @NonNull Integer id) {
        if (id == null) {
            throw new NullPointerException("id is marked non-null but is null");
        } else {
            this.id2 = id2;
            this.id = id;
        }
    }
@AllArgsConstructor


@Data = @Getter / @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor。



@Builder

函数式编程。

package com.geek.lombok;

import lombok.Builder;
import lombok.Data;
import lombok.NonNull;

@Data
@Builder
public class User {
    final int id2;
    @NonNull
    private Integer id;
    private String username;
    private String password;

    public static void main(String[] args) {

        User user = User.builder().id(1).username("geek").password("123").build();

        System.out.println("user = " + user);
}



@Log。

package com.geek.lombok;

import lombok.Builder;
import lombok.Data;
import lombok.NonNull;
import lombok.extern.java.Log;

@Data
@Builder
@Log
public class User {

    final int id2;
    @NonNull
    private Integer id;
    private String username;
    private String password;

    public static void main(String[] args) {

        User user = User.builder().id(1).username("geek").password("123").build();

        System.out.println("user = " + user);

        user.test("test_hello");
    }

    public void test(@NonNull String s) {
        System.out.println(s);
        log.info("log_info");
    }
}

 ~ 

user = User(id2=0, id=1, username=geek, password=123)
test_hello
Mar 28, 2020 12:19:48 AM com.geek.lombok.User test
INFO: log_info

在这里插入图片描述



val。

import lombok.val;

        // 编译时再指定类型。
        val map = new HashMap<>();


@Cleanup。

        @Cleanup InputStream inputStream = new FileInputStream("~/test.txt");
        @Cleanup OutputStream outputStream = new FileOutputStream("path");
        // 就不需要 .close(); 了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lyfGeek

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值