快速上手使用Lombok简化开发!

一、什么是Lombok

官网:Project Lombok

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.

Project Lombok是一个java库,它会自动插入到你的编辑器和构建工具中,为你的java增添色彩。
再也不用编写另一个 getter 或 equals 方法,只需一个注释,您的类就会有一个功能齐全的构建器,自动执行日志记录变量等等。 ---- 摘自官网

简而言之:Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。

二、快速使用Lombok

1.引入坐标

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

2.安装插件

在IDEA开发工具中使用Lombok时,需要安装Lombok插件来配合,好像现在新版的IDEA都已经内置了该插件,如果没有可以按照下面的操作进行按照即可!

打开IDEA的设置,点击Plugins,点击Browse repositories,在弹出的窗口中搜索lombok,然后安装即可。

3.使用示例

3.1不使用Lombok开发实体类

package cn.imyjs.mp.pojo;

/**
 * @Classname Student
 * @Description TODO
 * @Date 2022/4/24 15:04
 * @Created by YJS
 * @WebSite www.imyjs.cn
 */
public class Student {
    private Long id;
    private String name;
    private Integer age;
    private String address;

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

此时需要我们去手写实体类的Geter、Seter、toString、equals等方法,以及无参构造和全参构造器等,即使有许多一键自动生成的插件来简化这部分代码的手动书写,但是如果项目过于复杂的情况下,无疑也是一件头疼的事情,而且如果某实体类字段很多,还会导致代码冗长,不利于阅读和维护。那么此时使用Lombok就可以解决这些烦恼,往下看!

3.2使用Lombok开发实体类

package cn.imyjs.mp.pojo;

import lombok.Data;

/**
 * @Classname Student
 * @Description TODO
 * @Date 2022/4/24 15:04
 * @Created by YJS
 * @WebSite www.imyjs.cn
 */
@Data
public class Student {
    private Long id;
    private String name;
    private Integer age;
    private String address;
}

没错,此时这种写法与上边的写法效果相同,并且还提供hashcode等方法。只因为在这个类上加了一个@Data注解。

三、常用注解

1.变量相关

1.@NonNull

作用

这个注解会自动产生一个关于此参数的非空检查,如果参数为空,则抛出一个空指针异常。

使用范围

  • 方法参数上

    Lombok将在方法/构造函数体的开头插入一个空检查,并将参数的名称作为消息引发一个NullPointerException

  • 字段上

    任何为该字段赋值的生成方法也将生成这些空检查

示例

//成员方法参数加上@NonNull注解
public String getName(@NonNull Person p){
    return p.getName();
}

等价于:

public String getName( Person p){
    if(p==null){
        throw new NullPointerException("person");
    }
    return p.getName();
}

2.@Cleanup

作用

可以保证此变量代表的资源会被自动关闭,默认是调用资源的close()方法,如果该资源有其它关闭方法,可使用@Cleanup(“methodName”)来指定要调用的方法。

使用范围

这个注解用在变量前面。

示例

public static void main(String[] args) throws IOException {
        @Cleanup InputStream in = new FileInputStream("./a.txt");
        @Cleanup OutputStream out = new FileOutputStream("./b.txt");
        byte[] b = new byte[1024];
        while (true) {
            int r = in.read(b);
            if (r == -1) break;
            out.write(b, 0, r);
        }
    }

等价于:

public static void main(String[] args) throws IOException {
     InputStream in = new FileInputStream("./a.txt");
     try {
       OutputStream out = new FileOutputStream("./b.txt");
       try {
         byte[] b = new byte[1024];
         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();
       }
    }
}

2.实体类相关

1.@Getter & @Setter

作用

代替实体类中的geter和seter方法。

使用范围

  • 用在成员变量前面,相当于为成员变量生成对应的get和set方法,同时还可以为生成的方法指定访问修饰符,默认为public。
  • 直接用在上,可以为此类里的所有非静态成员变量生成对应的get和set方法。

示例

public class Student {
    @Getter(AccessLevel.PRIVATE)
    @Setter
    private Long id;
    @Getter(AccessLevel.PUBLIC)
    private String name;
    private Integer age;
    @Getter(AccessLevel.PRIVATE)
    @Setter(AccessLevel.PRIVATE)
    private String address;
}

方法命名

  • Getter

    默认情况下方法名为:get+字段名以驼峰连接。
    如果是boolean类型则:is+字段名以驼峰连接。(Boolean类型是get开头)

    不建议使用is开头的字段命名,会产生混淆

  • Setter

    setter不受boolean影响:set+字段名以驼峰连接。

特殊事项

  • @Getter可用于枚举而@Setter不能
  • 来自流行库的注释检查,例如javax.annotation.Nonnull,如果存在于字段上,导致生成的setter中会进行显式的空检查。
  • 当与@Accessors注解一起使用会产生影响

2.@Accessors

作用

修改getter和setter方法的内容。

使用范围

类或字段上

属性功能

  • fluent
    如果为true,那么getter 和setter 生成的方法名没有前缀。此外,除非指定,否则chain将为true。
  • chain
    如果为true,则生成的setter返回this而不是void。即可以使用链式编程。默认值:false
  • prefix
    如果存在,则字段必须以任何这些前缀为前缀。每个字段名称依次与列表中的每个前缀进行比较,如果找到匹配项,则会剥离前缀以创建字段的基本名称。在列表中包含一个空字符串是合法的它将始终匹配。

对于字母的字符,前缀后面的字符不能是小写字母,即以p为前缀也不会匹配pepper,但是pEpper会被匹配上(并且意味着该字段的基本名称epper)。

如果提供了前缀列表并且字段不以其中一个字段开头,则lombok将完全跳过该字段,并将生成警告

示例

@Accessors(chain = true)  // 开启链式编程
@Data
public class Student {
    private Long id;
    private String name;
    private Integer age;
    private String address;
}
    public static void main(String[] args) {
        Student student = new Student();
        student.setId(1001L).setAge(18).setName("小明").setAddress("北京");
        System.out.println(student);
        // Student(id=1001, name=小明, age=18, address=北京)
    }

3.@NoArgsConstructor/@RequiredArgsConstructor /@AllArgsConstructor

作用

  • @NoArgsConstructor:生成无参构造器
  • @AllArgsConstructor:生成全参构造器
  • @RequiredArgsConstructor:使用类中所有带有@NonNull注解的或者带有final修饰的成员变量生成对应的构造方法

    可以用做注入属性,在Spring中,在Controller层的类上使用@RequiredArgsConstructor标注,然后在类中创建对应的成员属性,就会自动在Controller类中,生成一个构造器,从而使属性注入。

使用范围

类上

注意

  • 成员变量都是非静态的
  • 如果类中含有final修饰的成员变量,是无法使用@NoArgsConstructor注解的
  • 三个注解都可以指定生成的构造方法的访问权限,同时,第二个注解还可以用@RequiredArgsConstructor(staticName=”methodName”)的形式生成一个指定名称的静态方法,返回一个调用相应的构造方法产生的对象。

示例

@RequiredArgsConstructor(staticName = "testMethod")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor
public class Shape {
    private int x;
    @NonNull
    private double y;
    @NonNull
    private String name;
}

等价于:

public class Shape {
    private int x;
    private double y;
    private String name;

    // @NoArgsConstructor
    public Shape(){
    }

    // @AllArgsConstructor(access = AccessLevel.PROTECTED)
    protected Shape(int x,double y,String name){
        this.x = x;
        this.y = y;
        this.name = name;
    }

    // @RequiredArgsConstructor(staticName = "testMethod")
    public Shape(double y,String name){
        this.y = y;
        this.name = name;
    }

    // @RequiredArgsConstructor(staticName = "testMethod")
    public static Shape testMethod(double y,String name){
        return new Shape(y,name);
    }
}

4.@Data

作用

@Data 是 @Getter、 @Setter、 @ToString、 @EqualsAndHashCode 和 @RequiredArgsConstructor 的快捷方式。

使用范围

类上

属性配置

  • staticConstructor 静态方法名

@Data(staticConstructor=“of”)
通过新的方式来创建实例:Foo.of(5)

示例

@Data(staticConstructor = "of")
public class Student {
    private Long id;
    private String name;
    private Integer age;
    private String address;
}
    public static void main(String[] args) {
        Student student = Student.of();
        student.setName("测试staticConstructor");
        System.out.println(student);
		// Student(id=null, name=测试staticConstructor, age=null, address=null)
    }

5.@Value

作用

@Value注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会生成set方法。

使用范围

类或字段上

特点

@Value是不可变的@Data

@ToString,@EqualsAndHashCode,@AllArgsConstructor,@FieldDefaults,@Getter。

所有字段由private和final修饰,不会产生setter方法。类本身也是由final修饰

6.@ToString

作用

生成toString()方法

使用范围

类上

属性功能

默认情况下,Lombok 生成包含所有成员变量的 toString 方法。可以通过 exclude 属性 @ToString(exclude={"someField","someOtherField"}) 覆盖行为将某些成员变量排除。或者用@ToString(of={“param1”,“param2”})来指定使用param1和param2两个成员变量。

示例

@Setter
@ToString(exclude = {"id"})
public class Student {
    private Long id;
    private String name;
    private Integer age;
    private String address;
}
public static void main(String[] args) {
        Student student = new Student();
        student.setId(1001L);
        student.setName("xm");
        student.setAge(19);
        student.setAddress("河南");
        System.out.println(student);
        // Student(name=xm, age=19, address=河南)
    }

7.@EqualsAndHashCode

作用

自动重写toString\equals\hashCode方法,还会生成一个canEqual方法,用于判断某个对象是否是当前类的实例,生成方法时只会使用类中的非静态和非transient成员变量。

使用范围

类上

功能属性

可以通过 exclude 属性 @EqualsAndHashCode(exclude={"someField","someOtherField"}) 覆盖行为将某些成员变量排除。或者用@EqualsAndHashCode(of={“param1”,“param2”})来指定使用param1和param2两个成员变量。

示例

@Setter
@EqualsAndHashCode(of = {"name","age"})
public class Student {
    private Long id;
    private String name;
    private Integer age;
    private String address;
}

3.日志相关

1.@Slf4j

作用

为类提供一个 属性名为log 的 log4j 日志对象。

使用范围

类上

示例

@Slf4j
public class LombokTest {
    public static void main(String[] args) {
        log.info("我是测试{}的", "@Slf4j");
        // 16:24:18.754 [main] INFO cn.imyjs.test.LombokTest - 我是测试@Slf4j的
    }
}

2.@Log4j

作用

为类提供一个 属性名为log 的 log4j 日志对象。

使用范围

类上

注意

  • @Log4j是具体的日志实现。而@Slf4j是一个抽象层,它允许程序使用任意一个日志类库,使程序更加独立。
  • @Slf4j可以使用占位符"{}",可减少代码中字符串连接次数

4.其他注解

1.@SneakyThrows

作用

可以将方法中的代码用try-catch语句包裹起来,捕获异常并在catch中用Lombok.sneakyThrow(e)把异常抛出,可以使用@SneakyThrows(Exception.class)的形式指定抛出哪种异常。

使用范围

方法上

示例

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

    @SneakyThrows
    public void run() {
        throw new Throwable();
    }
}

等价于:

public class SneakyThrows implements Runnable {
    @SneakyThrows(UnsupportedEncodingException.class)
    public String utf8ToString(byte[] bytes) {
        try{
            return new String(bytes, "UTF-8");
        }catch(UnsupportedEncodingException uee){
            throw Lombok.sneakyThrow(uee);
        }
    }

    @SneakyThrows
    public void run() {
        try{
            throw new Throwable();
        }catch(Throwable t){
            throw Lombok.sneakyThrow(t);
        }
    }
}

2.@Synchronized

作用

效果和synchronized关键字相同,区别在于锁对象不同,对于类方法和实例方法,synchronized关键字的锁对象分别是类的class对象和this对象,而@Synchronized得锁对象分别是私有静态final对象LOCK和私有final对象LOCK和私有final对象lock,当然,也可以自己指定锁对象。

使用范围

类方法或者实例方法上

示例

public class Synchronized {
    private final Object readLock = new Object();

    @Synchronized
    public static void hello() {
        System.out.println("world");
    }

    @Synchronized
    public int answerToLife() {
        return 42;
    }

    @Synchronized("readLock")
    public void foo() {
        System.out.println("bar");
    }
}

等价于:

public class Synchronized {
   private static final Object $LOCK = new Object[0];
   private final Object $lock = new Object[0];
   private final Object readLock = new Object();

   public static void hello() {
     synchronized($LOCK) {
       System.out.println("world");
     }
   }

   public int answerToLife() {
     synchronized($lock) {
       return 42;
     }
   }

   public void foo() {
     synchronized(readLock) {
       System.out.println("bar");
     }
   }
 }

3.@Builder

作用

生成构建者(Builder)模式。

 

四、Lombok的优缺点

1.优点

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

2.缺点

  • 不支持多种参数构造器的重载

 

微信关注

编程那点事儿

本站为非盈利性站点,所有资源、文章等仅供学习参考,并不贩卖软件且不存在任何商业目的及用途,如果您访问和下载某文件,表示您同意只将此文件用于参考、学习而非其他用途。
本站所发布的一切软件资源、文章内容、页面内容可能整理来自于互联网,在此郑重声明本站仅限用于学习和研究目的;并告知用户不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
如果本站相关内容有侵犯到您的合法权益,请仔细阅读本站公布的投诉指引页相关内容联系我,依法依规进行处理!
作者:理想
链接:https://www.imyjs.cn/archives/732
THE END
二维码
快速上手使用Lombok简化开发!
一、什么是Lombok 官网:Project Lombok Project Lo……
<<上一篇
下一篇>>
文章目录
关闭
目 录