前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >玩转lombok,好用的可不仅仅只有@Data

玩转lombok,好用的可不仅仅只有@Data

原创
作者头像
半月无霜
发布2024-08-08 15:24:21
1250
发布2024-08-08 15:24:21
举报
文章被收录于专栏:半月无霜

玩转lombok,好用的可不仅仅只有@Data

一、介绍

在开始前,我想先问问什么是lombok呢?

大家应该都听说过,它是一个Java库,通过注解的方式,帮助开发者消除Java代码中的样板代码,从而提高开发效率。

用的最熟悉的注解应该就是@Data了吧,它是一个复合注解,可以完成多个注解的功能@Getter@Setter@ToString@EqualsAndHashCode@RequiredArgsConstructor

那么这些注解都很熟悉了,下面介绍一些在lombok中不那么常用,但有时候异常好用的注解

二、注解

1)@Accessors

如下使用,可以进行链式调用

代码语言:java
复制
 package com.banmoon.lombok;
 ​
 import lombok.Data;
 import lombok.experimental.Accessors;
 import org.junit.Test;
 ​
 /**
  * @author banmoon
  * @date 2024/08/08 11:09:58
  */
 public class LombokAccessorsTest {
 ​
     @Test
     public void test() {
         // 最常用的,set链式方法
         AccessorsChainBO chainBO = new AccessorsChainBO()
                                        .setId(1)
                                        .setName("banmoon")
                                        .setEnabled(true);
         System.out.println(chainBO);
     }
 ​
 }
 ​
 @Data
 @Accessors(chain = true)
 class AccessorsChainBO {
     private Integer id;
     private String name;
     private Boolean enabled;
 }

还有一个fluent属性可以实现链式调用,不过不建议开启

它会导致set前缀没有了,有许多库都是使用反射setget方法来进行的,会导致第三方库找不到方法,从而导致报错

代码语言:java
复制
 package com.banmoon.lombok;
 ​
 import lombok.Data;
 import lombok.experimental.Accessors;
 import org.junit.Test;
 ​
 /**
  * @author banmoon
  * @date 2024/08/08 11:09:58
  */
 public class LombokAccessorsTest {
 ​
     @Test
     public void test() {
         // set前缀没有了,建议不要使用,有许多库都是使用反射set、get方法来进行的
         AccessorsFluentBO fluentBO = new AccessorsFluentBO()
                                               .id(1)
                                               .name("banmoon")
                                               .enabled(true);
         System.out.println(fluentBO);
     }
 ​
 }
 ​
 @Data
 @Accessors(fluent = true)
 class AccessorsFluentBO {
     private Integer id;
     private String name;
     private Boolean enabled;
 }

2)var、val

jdk10之后的版本,我们有个var的关键字,它允许开发者在声明变量时使用类型推断,使得代码更为简洁和易读。使用 var 声明变量时,编译器会根据变量的初始化表达式推断出变量的类型,从而避免显式地写出类型名称。

那么lombok中,引入了两个varval注解,同样可以达成类似的效果

对的没看错,是注解,不是关键字

如下进行使用

代码语言:java
复制
 package com.banmoon.lombok;
 ​
 import lombok.val;
 import lombok.var;
 import org.junit.Test;
 ​
 import java.util.ArrayList;
 import java.util.HashMap;
 ​
 /**
  * @author banmoon
  * @date 2024/08/08 11:42:47
  */
 public class LombokVarValTest {
 ​
     @Test
     public void test() {
         var list = new ArrayList<Integer>();
         list.add(1);
         list.add(2);
         System.out.println(list);
         val map = new HashMap<String, Object>();
         map.put("name", "banmoon");
         map.put("age", 18);
         System.out.println(map);
     }
 ​
 }

同样是类型推断,varval有什么区别

  • varjdk10之后的那个关键字是一样的,仅为类型推断
  • val相比之下,多出了一个final关键字,即声明了一个不可变对象

3)@Cleanup

Java代码中,不需要关注垃圾回收,但有一个一定要主动关闭,那便是文件IO

如果使用lombok,可以快速达成关闭流的写法,如下进行使用

代码语言:java
复制
 package com.banmoon.lombok;
 ​
 import lombok.Cleanup;
 import org.junit.Test;
 ​
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 ​
 /**
  * @author banmoon
  * @date 2024/08/08 12:01:12
  */
 public class LombokCleanupTest {
 ​
     @Test
     public void test() throws IOException {
         @Cleanup InputStream in = Files.newInputStream(Paths.get("/User/1.txt"));
         @Cleanup OutputStream out = Files.newOutputStream(Paths.get("/User/2.txt"));
         byte[] b = new byte[10000];
         while (true) {
             int r = in.read(b);
             if (r == -1) break;
             out.write(b, 0, r);
         }
     }
 ​
 }

其实从Java7开始,你可以使用try-with-resources语句来自动关闭实现了AutoCloseable接口的资源。这种方式确保即使在处理资源的过程中发生异常,资源也会被正确关毕

代码语言:java
复制
 package com.banmoon.lombok;
 ​
 import org.junit.Test;
 ​
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 ​
 /**
  * @author banmoon
  * @date 2024/08/08 12:01:12
  */
 public class LombokCleanupTest {
 ​
     @Test
     public void test1() throws IOException {
         Path inPath = Paths.get("/User/1.txt");
         Path outPath = Paths.get("/User/2.txt");
         try (InputStream in = Files.newInputStream(inPath);
              OutputStream out = Files.newOutputStream(outPath)) {
             byte[] b = new byte[10000];
             while (true) {
                 int r = in.read(b);
                 if (r == -1) break;
                 out.write(b, 0, r);
             }
         }
     }
 ​
 }

4)@FieldNameConstants

有些时候,我们需要类的属性名去完成一些逻辑,要么老老实实的写一遍常量,要么反射类获取属性名

lombok中,使用@FieldNameConstants注解在编译的时候,就生成对应类属性的常量,如下进行使用

代码语言:java
复制
 package com.banmoon.lombok;
 ​
 import cn.hutool.core.util.ReflectUtil;
 import cn.hutool.core.util.StrUtil;
 import lombok.Data;
 import lombok.experimental.FieldNameConstants;
 import org.junit.Test;
 ​
 import java.lang.reflect.Field;
 ​
 /**
  * @author banmoon
  * @date 2024/08/08 13:52:28
  */
 public class LombokFieldNameConstantsTest {
 ​
     @Test
     public void test() throws IllegalAccessException {
         FieldNameConstantsBO fieldNameConstantsBO = new FieldNameConstantsBO();
         fieldNameConstantsBO.setId(1);
         fieldNameConstantsBO.setName("banmoon");
         fieldNameConstantsBO.setEnabled(true);
         // 通过反射获取值
         Field field = ReflectUtil.getField(FieldNameConstantsBO.class, FieldNameConstantsBO.Fields.name);
         field.setAccessible(true);
         System.out.println(StrUtil.format("{}:{}", FieldNameConstantsBO.Fields.name, field.get(fieldNameConstantsBO)));
     }
 ​
 }
 ​
 @Data
 @FieldNameConstants
 class FieldNameConstantsBO {
     private Integer id;
     private String name;
     private Boolean enabled;
 }

另外,某些不需要生成常量的属性,我们可以使用lombok.experimental.FieldNameConstants.Exclude来达成

5)@SneakyThrows

在日常开发中,常常有检查异常需要显式的去处理,要么throws,要么catch。处理不说十分繁琐,总归还是有的

但在lombok中,可以使用@SneakyThrows注解来完成这个异常抛出,如下使用

代码语言:java
复制
 package com.banmoon.lombok;
 ​
 import lombok.SneakyThrows;
 import org.junit.Test;
 ​
 import java.util.concurrent.TimeUnit;
 ​
 /**
  * @author banmoon
  * @date 2024/08/08 14:19:27
  */
 public class LombokSneakyThrowsTest {
 ​
     @Test
     @SneakyThrows
     public void test() {
         TimeUnit.SECONDS.sleep(1);
     }
 ​
 }

6)@Synchronized

同步锁synchronized大家都很熟悉,但lombok连这个都要简化,我感觉没必要

代码语言:java
复制
 package com.banmoon.lombok;
 ​
 import lombok.Synchronized;
 ​
 /**
  * @author banmoon
  * @date 2024/08/08 15:06:11
  */
 public class LombokSynchronizedTest {
 ​
     private static final Object lock = new Object();
 ​
     @Synchronized
     public void test() {
         System.out.println(1);
     }
 ​
     @Synchronized("lock")
     public void test1() {
         System.out.println(1);
     }
 ​
     @Synchronized
     public static void staticTest() {
         System.out.println(1);
     }
 ​
 }

编译后是这个样子的

代码语言:java
复制
 //
 // Source code recreated from a .class file by IntelliJ IDEA
 // (powered by FernFlower decompiler)
 //
 ​
 package com.banmoon.lombok;
 ​
 public class LombokSynchronizedTest {
     private final Object $lock = new Object[0];
     private static final Object $LOCK = new Object[0];
     private static final Object lock = new Object();
 ​
     public LombokSynchronizedTest() {
     }
 ​
     public void test() {
         synchronized(this.$lock) {
             System.out.println(1);
         }
     }
 ​
     public void test1() {
         synchronized(lock) {
             System.out.println(1);
         }
     }
 ​
     public static void staticTest() {
         synchronized($LOCK) {
             System.out.println(1);
         }
     }
 }

可以看到是同步代码块,如果没有指定value,它会自己生成一个Object

静态方法使用的话,也是使用静态的Object变量

三、最后

为什么没有@Builder,我在调试的时候出现了一点问题,这个也比较常用,需要单开一篇来解决

我是半月,另附带官网地址

Project Lombok

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 玩转lombok,好用的可不仅仅只有@Data
    • 一、介绍
      • 二、注解
        • 1)@Accessors
        • 2)var、val
        • 3)@Cleanup
        • 4)@FieldNameConstants
        • 5)@SneakyThrows
        • 6)@Synchronized
      • 三、最后
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档