Java Lombok不常用注解

参考资料

  1. 最全的 lombok 注解详情(随着版本不定时更新)
  2. @Accessors 注解极简教程
  3. Lombok工具 : 常用注解介绍 (全)
  4. Lombok Experimental features
  5. Lombok注解之@With
  6. @FieldNameConstants(自动生成字段名称常量)
  7. 【Lombok】@FieldNameConstants | 为你的字段生成一个以字段名称为值的常量


一. @Accessors

  • 可以同时作用于类和属性上,属性上的优先级 > 类上的优先级

1.1 fluent 属性

  • 默认值为false
  • 当为 true 时,对应字段的 getter 方法前面就没有 get,setter 方法就不会有 set
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(fluent = true)
public class Student {

    private String personId;

    private String personName;

    private String age;

    private String address;

    public static void main(String[] args) {
        
        Student student = new Student();
        
        // 不需要set
        student.age("1");
        student.address("地球");
    
        // 不需要get
        student.personId();
        student.personName();
    }
}

1.2 chain 属性

  • 默认值为false
  • 当为 true 时,对应字段的 setter 方法调用后,会返回当前对象
import lombok.Data;
import lombok.experimental.Accessors;

@Data
// 作用于类上,表示所有的属性都可以链式调用
@Accessors(chain = true)
public class Student {

    private String personId;

    private String personName;
	
	// 作用于属性上,表示这个属性不链式调用
    @Accessors(chain = false)
    private String age;

    private String address;

    public static void main(String[] args) {

        Student student = new Student();

        student.setPersonId("1")
                .setPersonName("贾飞天")
                // age属性并不链式调用,所以不会返回对象本身
                .setAge("10");
    }
}

1.3 prefix 属性

  • 该属性是一个字符串数组
  • 当该数组有值时,表示忽略字段中对应的前缀,生成对应的 getter 和 setter 方法。
import lombok.Data;
import lombok.experimental.Accessors;

@Data
// 忽略属性前缀person和human,并且链式调用
@Accessors(prefix = {"person", "human"}, chain = true)
public class Student {

    private String personId;

    private String humanName;
    
    private String age;

    private String address;

    public static void main(String[] args) {

        Student student = new Student();
        // 前缀person和human被忽略
        student.setId("1")
                .setName("贾飞天")
                .setAge("18")
                .setAddress("地球");
    }
}

二. @Builder

  • 通过建造者模式创建对象
  • 会生成一个全参的构造函数,如果我们使用无参构造函数的话就会报错
import lombok.Builder;
import lombok.ToString;

@Builder
@ToString
public class Student {

    private String personId;

    private String humanName;

    private String age;
	
	// 非 final 的字段可以有默认值
    @Builder.Default
    private String address = "地球";

    public static void main(String[] args) {

        Student student = Student.builder()
                .personId("1")
                .humanName("贾飞天")
                .age("10")
                // 没有创建address属性
                .build();
        System.out.println(student);
        /*
        	因为我们使用@Builder.Default给address指定了默认值
        	Student(personId=1, humanName=贾飞天, age=10, address=地球)
		*/
    }
}

三. @Singular

  • 该注解需要配合@Builder注解使用,用于注解一个集合字段
  • 如果没有指定value值的话,那么集合字段名需要是复数形式
  • 如果指定了value值,集合字段名就是我们指定的value值
  • 会生成添加元素方法向集合添加单个元素
import lombok.Builder;
import lombok.Data;
import lombok.Singular;

import java.util.List;

@Builder
@Data
public class Student {

    private String personId;

    private String humanName;

    private String age;

    /**
     * 属性名结尾不为 s ,
     * 因此必须在@Singular注解中手动指定构建时使用的名称
     */
    @Singular("address")
    private List<String> addressList;

    /**
     * 属性名结尾为 s,
     * 因此可以不手动指定构建时使用的名称,该名称为去掉s之后的属性名
     */
    @Singular
    private List<String> hobbys;

    public static void main(String[] args) {


        Student student = Student.builder()
                .personId("110")
                .humanName("贾飞天")
                // 可以一个一个向集合中添加元素,无需创建一个集合
                .address("地球").address("火星")
                // 也可以直接添加集合
                .addressList(Arrays.asList("宇宙", "银河系"))
                // 因为hobbys这个属性名以s结尾,所以添加单个元素的时候,用去掉s的属性名即可
                .hobby("吃饭").hobby("睡觉")
                .hobbys(Arrays.asList("学习java", "学习Python"))
                .build();
        System.out.println(student);
        /**
         Student(
         	personId=110
         	, humanName=贾飞天
         	, age=null
         	, addressList=[地球, 火星, 宇宙, 银河系]
         	, hobbys=[吃饭, 睡觉, 学习java, 学习Python]
		 )
        */
    }
}

四. @Cleanup

  • 作用于局部变量,可以自动关闭资源
  • 仅针对实现了java.io.Closeable接口的对象有效
import lombok.Cleanup;
import java.io.File;
import java.io.FileInputStream;

public static void main(String[] args) throws IOException {

    @Cleanup FileInputStream inputStream = new FileInputStream(new File("D:\\test\\application.yml"));
    byte[] bytes = inputStream.readAllBytes();
    System.out.println(Arrays.toString(bytes));
}

👉编译后

在这里插入图片描述


五. @RequiredArgsConstructor

⏹具体使用请参考这篇博客
SpringBoot 使用lombok的@RequiredArgsConstructor注解进行Bean注入


六. @ExtensionMethod

  • 作用于类,向类中添加方法。
  • 要添加的方法的修饰符必须是 public,必须是静态方法,方法必须要有对应的参数,变量必须初始化。

⏹定义一个工具类

public class StringExtension {

	// 判断字符串是否为null或者空字符串
	public static boolean isNullOrEmpty(String str) {

		if (str == null || str.equals("")) {
			return true;
		} 
		
		return false;
	}
	
	// 判断不是null或空字符串
	public static boolean isNotNullOrEmpty(String str) {

		return !isNullOrEmpty(str);
	}
}

⏹使用👇

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;
import lombok.experimental.ExtensionMethod;

@Service
// 将StringExtension类添加到当前类中
@ExtensionMethod({ StringExtension.class })
public class Test implements CommandLineRunner {

	@Override
	public void run(String... args) throws Exception {
		
		// 需要做判断的值
		String value = null;
		
		// 😅使用@ExtensionMethod注解之前的常规写法
		boolean valueResult1 = StringExtension.isNullOrEmpty(value);
		System.out.println(valueResult1);  // true
		
		/**
		 * 💪使用@ExtensionMethod注解之后,
		 * StringExtension类中的方法默认添加到当前类中,
		 * 虽然value的值为null,但是在编译的时候会进行处理,处理为常规写法这种形式
		 */
		boolean valueResult2 = value.isNullOrEmpty();
		System.out.println(valueResult2);  // true
	}
}

7. @UtilityClass

  • 将普通类转换为工具类
  • 被该注解作用的类无法实例化,并且该类会添加final
  • 该类中的属性和方法都会被添加static

⏹被@UtilityClass注解作用的类

import lombok.experimental.UtilityClass;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@UtilityClass
public class Base64Utils {

    private final Base64.Encoder encoder = Base64.getEncoder();
    private final Base64.Decoder decoder = Base64.getDecoder();

    // 加密
    public String encode(String text) {
        return encoder.encodeToString(text.getBytes(StandardCharsets.UTF_8));
    }

    // 解密
    public String decode(String encodedText) {
        return new String(decoder.decode(encodedText), StandardCharsets.UTF_8);
    }
}

⏹编译完成之后

  • private Base64Utils() { }构造方法是lombok自动生成的。
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;

public final class Base64Utils {
    private static final Encoder encoder = Base64.getEncoder();
    private static final Decoder decoder = Base64.getDecoder();

    public static String encode(String text) {
        return encoder.encodeToString(text.getBytes(StandardCharsets.UTF_8));
    }

    public static String decode(String encodedText) {
        return new String(decoder.decode(encodedText), StandardCharsets.UTF_8);
    }
	
    private Base64Utils() {
        throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
    }
}

八. @FieldDefaults

⏹用来指定类和属性的访问修饰符,也可以用来添加final

8.1 level

  • 用来指定属性的修饰符,可指定为
    • PUBLIC
    • MODULE
    • PROTECTED
    • PACKAGE
    • PRIVATE
  • 如果属性上本身就存在修饰符的话,使用属性上自带的修饰符
  • 只作用于属性,不作用于方法上
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class ZTestEntity {

    // 手动指定了修饰符
    public String id;
    protected String address;

    // 没有指定修饰符
    String name;
    Boolean isAdmin;
    
    // 只作用于属性,不作用于方法上
	String getData() {
        return "";
    }
}

⏹编译之后的效果

public class ZTestEntity {
    public String id;
    protected String address;
    private String name;
    private Boolean isAdmin;

    public ZTestEntity() {
    }

    String getData() {
        return "";
    }
}

8.2 makeFinal

  • 用来将属性指定为final
  • 指定的范围是类上的所有属性,不想被指定final的属性,使用@NonFinal注解来修饰
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import lombok.experimental.NonFinal;

@FieldDefaults(level = AccessLevel.PUBLIC, makeFinal = true)
public class ZTestEntity {

    // 使用@NonFinal注解,避免被final化
    @NonFinal
    public String id = "";
    protected String address = "";

    // 没有指定修饰符
    @NonFinal
    String name = "";
    Boolean isAdmin = true;
}

⏹编译之后的效果

public class ZTestEntity {
    public String id = "";
    protected final String address = "";
    public String name = "";
    public final Boolean isAdmin = true;

    public ZTestEntity() {
    }
}

九. @FieldNameConstants

  • 作用于类上,用于为属性生成一个常量,常量值和属性名相同
import lombok.experimental.FieldNameConstants;

@FieldNameConstants
public class Test34Entity {

    private String id;

    private String name;

    private String content;
}
  • 编译后
public class Test34Entity {
    private String id;
    private String name;
    private String content;

    public Test34Entity() {
    }

    public static final class Fields {
        public static final String content = "content";
        public static final String name = "name";
        public static final String id = "id";

        public Fields() {
        }
    }
}
  • 使用
public static void main(String[] args) {

	// 得到属性名所对应的属性值
    String id = Test34Entity.Fields.id;
    System.out.println(id);  // id

    String content = Test34Entity.Fields.content;
    System.out.println(content);  // content
}

9.1 asEnum 生成枚举类

  • 配置asEnum = true
import lombok.experimental.FieldNameConstants;

@FieldNameConstants(asEnum = true)
public class Test34Entity {

    private String id;

    private String name;

    private String content;
}
  • 编译后,在类的内部生成了枚举类
public class Test34Entity {
    private String id;
    private String name;
    private String content;

    public Test34Entity() {
    }

    public static enum Fields {
        id,
        name,
        content;

        private Fields() {
        }
    }
}

9.2 innerTypeName 指定内部类名称

  • 配置innerTypeName = "名称"
import lombok.experimental.FieldNameConstants;

@FieldNameConstants(innerTypeName = "Fyh")
public class Test34Entity {

    private String id;

    private String name;

    private String content;
}
  • 编译后
public class Test34Entity {
    private String id;
    private String name;
    private String content;

    public Test34Entity() {
    }

    public static final class Fyh {
        public static final String content = "content";
        public static final String name = "name";
        public static final String id = "id";

        public Fyh() {
        }
    }
}

9.3 onlyExplicitlyIncluded 只引入指定字段

  • onlyExplicitlyIncluded = true + @FieldNameConstants.Include指定需要生成的字段
  • @FieldNameConstants.Exclude:用来排除指定字段
import lombok.experimental.FieldNameConstants;

@FieldNameConstants(onlyExplicitlyIncluded  = true)
public class Test34Entity {

    @FieldNameConstants.Include
    private String id;

    private String name;

    private String content;
}
  • 编译后
public class Test34Entity {
    private String id;
    private String name;
    private String content;

    public Test34Entity() {
    }

    public static final class Fields {
        public static final String id = "id";

        public Fields() {
        }
    }
}

十. @With

  • 作用于类或类中的属性,生成多个with + 变量名的方法,返回当前对象的副本(新对象)
  • 需要有全参数的构造方法,配合@AllArgsConstructor注解使用
import lombok.*;

// value = AccessLevel.PROTECTED 指定生成的with方法的修饰符
@With(value = AccessLevel.PROTECTED)
@AllArgsConstructor
@ToString
public class ZTestEntity {

    private String id;

    private String address;
}

⏹编译之后的效果

  • withId()withAddress()方法上可以看到如果指定了新的属性值的话,返回的是新的对象
  • 由于@With(value = AccessLevel.PROTECTED)指定了PROTECTED,因此生成的with方法也是protected 的修饰符
public class ZTestEntity {
    private String id;
    private String address;

    protected ZTestEntity withId(String id) {
        return this.id == id ? this : new ZTestEntity(id, this.address);
    }

    protected ZTestEntity withAddress(String address) {
        return this.address == address ? this : new ZTestEntity(this.id, address);
    }

    public ZTestEntity(String id, String address) {
        this.id = id;
        this.address = address;
    }

    public String toString() {
        return "ZTestEntity(id=" + this.id + ", address=" + this.address + ")";
    }
}

⏹使用with方法构造新对象

// 通过构造方法构造一个对象
ZTestEntity entity = new ZTestEntity("1", "地球");
System.out.println(entity);  // ZTestEntity(id=1, address=地球)

// 通过@With注解生成的with方法构造的是原对象的副本,只需改动属性,就可以生成新的对象
ZTestEntity entity1 = entity.withId("2");
System.out.println(entity1);  // ZTestEntity(id=2, address=地球)

ZTestEntity entity2 = entity.withAddress("月球");
System.out.println(entity2);  // ZTestEntity(id=1, address=月球)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Lombok是一个Java库,用于简化Java代码。常用的注解有: 1. @Data: 用于生成getter、setter、toString、equals和hashCode方法。 2. @Getter/@Setter: 分别用于生成getter和setter方法。 3. @ToString: 用于生成toString方法。 4. @EqualsAndHashCode: 用于生成equals和hashCode方法。 5. @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor: 分别用于生成无参构造器、有参构造器和全参构造器。 6. @Builder: 用于生成Builder模式的类。 7. @Synchronized: 用于生成同步方法。 8. @Log: 用于生成日志记录的字段。 ### 回答2: Lombok是一个在Java编程中常用的工具库,它提供了一些常用注解,用于简化代码编写和减少样板代码的重复。 1. @Getter和@Setter:使用在类或字段上,自动生成getter和setter方法。 2. @ToString:使用在类上,自动生成toString方法。 3. @EqualsAndHashCode:使用在类上,自动生成equals和hashCode方法。 4. @NoArgsConstructor和@AllArgsConstructor:使用在类上,自动生成无参构造方法和全参构造方法。 5. @RequiredArgsConstructor:使用在类上,为final字段生成构造方法。 6. @Data:使用在类上,自动生成@Getter、@Setter、@ToString、@EqualsAndHashCode等方法。 7. @Builder:使用在类或者方法上,生成Builder模式的代码,用于构建对象。 8. @Log:使用在类上,自动生成日志相关的代码。 除了上述常用注解外,Lombok还提供了其他一些注解,如@NonNull用于标识字段不可为空、@Cleanup用于自动关闭资源、@Synchronized用于生成同步代码等等。这些注解可以根据需求灵活使用,因此在日常开发中可以大大简化代码编写和提高开发效率。 需要注意的是,Lombok注解在编译时通过AST(抽象语法树)技术修改了源代码,因此在阅读和调试时需要特别留意对应的修改。此外,使用Lombok需要在开发环境中添加相应的插件或配置,以确保代码顺利编译和运行。 ### 回答3: Lombok是一个Java开发工具,它通过使用注解来简化Java代码的编写,提高开发效率。下面是Lombok常用注解: 1. @Getter/@Setter:自动生成属性的getter和setter方法。 2. @NonNull:标注在方法参数上,如果参数传入null值,则会抛出空指针异常。 3. @NoArgsConstructor:生成一个无参的构造方法。 4. @RequiredArgsConstructor:生成一个带有final或者@NonNull注解的属性的构造方法。 5. @AllArgsConstructor:生成一个包含所有属性的构造方法。 6. @Builder:将类标记为builder模式,自动生成builder方法。 7. @ToString:生成toString方法。 8. @EqualsAndHashCode:生成equals和hashCode方法。 9. @Data:包含@Getter、@Setter、@ToString、@EqualsAndHashCode和@RequiredArgsConstructor的组合注解。 10. @Log:生成简单的日志输出方法,可以用于替代手动创建logger。 11. @Slf4j:使用SLF4J生成日志输出方法。 12. @Value:类似于@Data,但是生成的是不可变类。 13. @AllArgsConstructor(staticName = "of"):生成一个带有所有参数的静态工厂方法。 14. @Delegate:生成委托类,用于将某个属性或方法委托给另一个类进行处理。 这些都是Lombok常用注解,可以大大简化Java代码的编写,减少了一些重复性的工作,提高了开发效率。需要注意的是,在使用Lombok时,需要在项目的构建工具(如Maven或Gradle)中添加相应的依赖。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值