Java Lombok使用介绍

426 阅读5分钟

简介

​ Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法,提高开发人员的效率。

​ 例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。

使用方法

1、下载插件

​ 在idea上使用时,需安装lombok插件,settings -> plugins 搜索lombok下载安装,在离线状态时可去lombok官网下载zip包,再导入idea中。

注意:官网下载lombok包时,要注意和idea版本相对应,版本不同会安装不成功。 查看idea版本号 Help -> About

2、导入依赖

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

3、注解使用

1、@Data

​ @Data注解在类上,会为类的所有属性自动生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。

import lombok.Data;

@Data 
public class Student {
    private int id;
    private String name;

    public static void main(String[] args) {
        Student s1 = new Student();

        s1.setId(1);
        s1.setName("alex");
        System.out.println(s1.toString());

        Student s2 = new Student();
        s2.setId(2);
        s2.setName("shelly");
        System.out.println(s2.toString());

        System.out.println("equals : "+s1.equals(s2));
        System.out.println("hashcode : "+s1.hashCode());
        System.out.println("hashcode : "+s2.hashCode());

        System.out.println("canEqual : "+s1.canEqual(s2));

    }
}

运行结果:

Student(id=1, name=alex)
Student(id=2, name=shelly)
equals : false
hashcode : 3000306
hashcode : -903449000
canEqual : true

​ 如果不使用lombok注释,则需要alt+insert自动生成这些代码,略微有些繁琐

2、@Getter/@Setter

​ @Getter/@Setter注解,此注解在属性上,可以为相应的属性自动生成Getter/Setter方法

3、@ToString

​ 生成toString方法,默认包含所有字段,也可设置不包含哪些字段@ToString(exclude = "id")不包含id字段

4、@EqualsAndHashCode

​ 生成equals和hashCode方法,默认情况下,会使用所有非静态(non-static)和非瞬态(non-transient)属性来生成equals和hasCode,也能通过exclude注解来排除一些属性。

5、@AllArgsConstructor

​ 生成全参构造器

import lombok.AllArgsConstructor;
//若直接使用@AllArgsConstructor标签,则直接生成全参构造器,不会生成getInstance方法
@AllArgsConstructor(staticName = "getInstance")		//getInstance为自定义的方法名
public class Person {
    private int id;
    private String name;
}

上述代码经lombok编译后会生成如下代码

import lombok.AllArgsConstructor;

public class Person {
    private int id;
    private String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public static Person getInstance(int id,String name){
        return new Person(id,name);
    }
}

6、@RequiredArgsConstructor

​ 为指定类必须初始化的成员变量,如 final 成员变量,生成对应的构造函数

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class Dog {
    private final int id;
    private String name;
}

上述代码经lombok编译后会生成如下代码

public class Dog {
    @Getter
    private final int id;
    @Getter @Setter
    private String name;

    public Dog(int id) {
        this.id = id;
    }
}

7、@NoArgsConstructor

​ 生成无参构造器 可用@NoArgsConstructor(force = true),然后就会为没有初始化的final字段设置默认值 0 / flase / null

import lombok.NoArgsConstructor;

@NoArgsConstructor(staticName = "getInstance")	//getInstance为自定义的方法名
public class Animal {
    private int id;
    private String name;
}

上述代码经lombok编译后会生成如下代码

public class Animal {
    private int id;
    private String name;

    public Animal(){}

    public static Animal getInstance(){
        return new Animal();
    }

}

注解实例:

import lombok.*;

@ToString
@EqualsAndHashCode
@AllArgsConstructor		
@NoArgsConstructor		
public class User {
    @Getter@Setter		
    private int id;
    @Getter@Setter
    private int age;
    @Getter@Setter
    private String name;

    public static void main(String[] args) {
        User u1 = new User();
        u1.setId(1);
        u1.setAge(20);
        u1.setName("alex");
        System.out.println(u1);

        User u2 = new User(2,21,"shelly");
        System.out.println(u2);
        System.out.println("equals : " + u1.equals(u2));
        System.out.println("hashcode : " + u1.hashCode());
        System.out.println("hashcode : " + u2.hashCode());
    }
}

运行结果:
    User(id=1, age=20, name=alex)
    User(id=2, age=21, name=shelly)
    equals : false
    hashcode : 3206806
    hashcode : -903239019

8、@Cleanup

​ 该注解能帮助我们自动调用close()方法,很大的简化了代码。

public class CleanUpTest {
    public static void main(String[] args) throws Exception {
        @Cleanup InputStream is = new FileInputStream("");
        @Cleanup OutputStream out = new FileOutputStream(args[1]);
        byte[] b = new byte[10000];
        while (true) {
            int r = is.read(b);
            if (r == -1) break;
            out.write(b, 0, r);
        }
    }
}

不使用@Cleanup注解写法

public class CleanUpTest {
    public static void main(String[] args) throws Exception {
        InputStream in = new FileInputStream(args[0]);
        try {
            OutputStream out = new FileOutputStream(args[1]);
            try {
                byte[] b = new byte[10000];
                while (true) {
                    int r = in.read(b);
                    if (r == -1) break;
                    out.write(b, 0, r);
                }
            } finally {
                if (out != null) {
                    out.close();		//关闭资源
                }
            }
        } finally {
            if (in != null) {
                in.close();				//关闭资源
            }
        }
    }
}

更多注解使用请参照lombok官方文档

projectlombok.org/

4、Lombok的优缺点

优点:

  1. 能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,提高了一定的开发效率;
  2. 让代码变得简洁,不用过多的去关注相应的方法;
  3. 属性做修改时,也简化了维护为这些属性所生成的getter/setter方法等;

缺点:

  1. 不支持多种参数构造器的重载
  2. jdk版本问题,支持jdk8,jdk版本升级后可能会出现不兼容现象
  3. 代码耦合度增加,某一模块使用lombok后,其他依赖于此模块的代码都需要引入lombok依赖
  4. 虽然省去了手动创建getter/setter方法的麻烦,但大大降低了源代码的可读性和完整性,降低了阅读源代码的舒适度;