语法篇之Lombok简介

r囧r小猫 2024-04-17 13:28 172阅读 0赞

一、概述

1.1简介

Lombok是一个Java库,能自动插入编辑器并构建工具,简化Java开发。通过添加注解的方式,不需要为类编写getter或eques方法,同时可以自动化日志变量。官网链接

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

1.2环境依赖

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. <version>1.18.18</version>
  5. <scope>compile</scope>
  6. </dependency>

1.3常用注解

  • @Setter 注解在类或字段,注解在类时为所有字段生成setter方法,注解在字段上时只为该字段生成setter方法。
  • @Getter 使用方法同上,区别在于生成的是getter方法。
  • @ToString 注解在类,添加toString方法。
  • @EqualsAndHashCode 注解在类,生成hashCode和equals方法。
  • @NoArgsConstructor 注解在类,生成无参的构造方法。
  • @RequiredArgsConstructor 注解在类,为类中需要特殊处理的字段生成构造方法,比如final和被@NonNull注解的字段。
  • @AllArgsConstructor 注解在类,生成包含类中所有字段的构造方法。
  • @Data 注解在类,生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。
  • @Slf4j 注解在类,生成log变量,严格意义来说是常量。private static final Logger log = LoggerFactory.getLogger(UserController.class);

二、注解详解和示例

2.1val和var

Lombok的val和var是两种用于简化局部变量声明的注解,它们可以根据初始化表达式自动推断变量的类型,从而避免编写冗余的类型声明。val和var的区别在于,val声明的变量是final的,不能再次赋值,而var声明的变量是非final的,可以再次赋值,但必须与初始类型一致。

  1. // 使用val声明一个final类型的String变量
  2. val name = "Bing";
  3. // 使用var声明一个非final类型的Integer变量
  4. var age = 10;
  5. // 使用val声明一个final类型的List<String>变量
  6. val list = new ArrayList<String>();
  7. list.add("Hello");
  8. // 使用var声明一个非final类型的Map<Integer, String>变量
  9. var map = new HashMap<Integer, String>();
  10. map.put(1, "One");

缺点

  • val和var只能用于局部变量和foreach循环中,不能用于类属性(成员变量)或方法参数。
  • val和var必须有一个初始化表达式,否则会报错。例如,val x;var y;是不合法的。
  • val和var只能推断出引用类型,不能推断出基本类型。例如,val x = 10;会推断出Integer类型而不是int类型。
  • val和var不能用于泛型参数或数组初始化。例如,List<val> list = new ArrayList<val>();val array = {1, 2, 3};是不合法的。

2.2@NonNull

@NonNull是一个用于标识Java类中的属性、方法参数或返回值不能为null的注解。它可以帮助您编写更加健壮的代码,避免空指针异常的发生

  1. public void notNullExample(@NonNull String string) {
  2. string.length();
  3. }
  4. //=>相当于
  5. public void notNullExample(String string) {
  6. if (string != null) {
  7. string.length();
  8. } else {
  9. throw new NullPointerException("null");
  10. }
  11. }

@NonNull也可以用于属性上,Lombok会在编译时自动生成非空检查代码,如果属性为null,就会抛出一个NullPointerException异常

  1. @Data
  2. public class User {
  3. @NonNull private String name;
  4. private Integer age;
  5. }

2.3@Cleanup

@Cleanup是一个用于自动管理资源,安全地调用close方法的注解。它可以帮助您避免忘记关闭文件对象,数据库资源等可能引发内存溢出的情况。它也可以使您的代码更加简洁,不需要编写冗余的try-finally语句。

@Cleanup可以用于任何局部变量声明,只需要在变量类型前加上@Cleanup注解,Lombok会在编译时自动生成非空检查和关闭资源的代码

  1. public static void main(String[] args) {
  2. try {
  3. @Cleanup InputStream inputStream = new FileInputStream(args[0]);
  4. } catch (FileNotFoundException e) {
  5. e.printStackTrace();
  6. }
  7. //=>相当于
  8. InputStream inputStream = null;
  9. try {
  10. inputStream = new FileInputStream(args[0]);
  11. } catch (FileNotFoundException e) {
  12. e.printStackTrace();
  13. } finally {
  14. if (inputStream != null) {
  15. try {
  16. inputStream.close();
  17. } catch (IOException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. }
  22. }

@Cleanup默认调用close方法来关闭资源,但是您也可以指定其他的方法名,只需要在@Cleanup后面加上括号和方法名即可

  1. // 使用@Cleanup注解声明一个Socket对象,并指定使用shutdownInput方法来关闭资源
  2. @Cleanup("shutdownInput") Socket socket = new Socket("somehost", 1234);

@Cleanup只能用于局部变量,不能用于类属性(成员变量)或方法参数

2.4@Getter/@Setter (常用)

@Getter和@Setter的生成的方法默认是public的,除非您显式指定一个AccessLevel,例如@Setter(AccessLevel.PROTECTED)。合法的访问级别有PUBLIC, PROTECTED, PACKAGE, 和 PRIVATE

  1. @Setter(AccessLevel.PUBLIC)
  2. @Getter(AccessLevel.PROTECTED)
  3. private int id;
  4. private String shap;

2.5@ToString(常用)

@ToString是Lombok库提供的一个注解,用于为类的对象自动生成toString()方法,从而简化代码,提高开发效率

  1. // 使用@ToString注解声明一个Account类
  2. @ToString
  3. public class Account {
  4. private String id;
  5. private String name;
  6. // standard getters and setters
  7. }
  8. // 创建一个Account对象并调用toString()方法
  9. Account account = new Account();
  10. account.setId("12345");
  11. account.setName("An account");
  12. System.out.println(account.toString());
  13. // 输出结果如下:
  14. Account(id=12345, name=An account)

2.6构造函数(常用)

@NoArgsConstructor

@NoArgsConstructor:这个注解用于生成一个无参的构造器。如果类中有final或非空(non-null)的字段,那么默认情况下,这个注解会导致编译错误,除非设置force=true,那么所有final或非空字段都会被初始化为0/false/null

  1. // 使用@NoArgsConstructor注解声明一个User类
  2. @NoArgsConstructor
  3. public class User {
  4. private String name;
  5. private int age;
  6. // standard getters and setters
  7. }
  8. // 创建一个User对象并调用无参构造器
  9. User user = new User();

@RequiredArgsConstructor

@RequiredArgsConstructor:这个注解用于生成一个带有特定参数的构造器。所有未初始化的final字段和被@NonNull注解标记的字段都会作为构造器的参数

  1. // 使用@RequiredArgsConstructor注解声明一个Student类
  2. @RequiredArgsConstructor
  3. public class Student {
  4. private final String name;
  5. @NonNull private int age;
  6. // standard getters and setters
  7. }
  8. // 创建一个Student对象并调用带有参数的构造器
  9. Student student = new Student("Alice", 20);

@AllArgsConstructor

@AllArgsConstructor:这个注解用于生成一个带有所有字段参数的构造器

  1. // 使用@AllArgsConstructor注解声明一个Person类
  2. @AllArgsConstructor
  3. public class Person {
  4. private String name;
  5. private int age;
  6. private String gender;
  7. // standard getters and setters
  8. }
  9. // 创建一个Person对象并调用带有所有参数的构造器
  10. Person person = new Person("Bob", 25, "male");

2.7@Data

@Data是一个用于为类提供一系列功能的注解,包括:

  • 为类的所有属性生成getter和setter方法
  • 为类生成equals和hashCode方法,用于判断对象是否相等和计算哈希值
  • 为类生成toString方法,用于返回对象的字符串表示
  • 为类生成一个无参构造器和一个全参构造器,用于创建对象实例
  • 为类生成canEqual方法,用于判断其他对象是否可以与当前对象比较
  1. // 使用@Data注解声明一个User类
  2. @Data
  3. public class User {
  4. private String name;
  5. private int age;
  6. }
  7. // 创建一个User对象并调用相关方法
  8. User user = new User();
  9. user.setName("Alice");
  10. user.setAge(20);
  11. System.out.println(user.getName()); // Alice
  12. System.out.println(user.getAge()); // 20
  13. System.out.println(user.toString()); // User(name=Alice, age=20)
  14. System.out.println(user.hashCode()); // 2129789493
  15. User user2 = new User();
  16. user2.setName("Alice");
  17. user2.setAge(20);
  18. System.out.println(user.equals(user2)); // true

@Data注解在生成equals和hashCode方法时,会考虑当前类和父类中的所有属性。这可能会导致一些意想不到的结果,例如子类对象与父类对象相等,或者不同类型的对象相等34。为了避免这种情况,您可以使用@EqualsAndHashCode(callSuper = false)注解来覆盖@Data注解的默认行为,只考虑当前类中的属性

2.8@Value 和@Data的异同

  • @Value和@Data都可以为类的所有属性生成getter方法,为类生成equals和hashCode方法,用于判断对象是否相等和计算哈希值,为类生成toString方法,用于返回对象的字符串表示,为类生成canEqual方法,用于判断其他对象是否可以与当前对象比较。
  • @Value和@Data的不同之处在于,@Value会将类的所有属性声明为final和private,使得类不可变,因此只会生成一个全参构造器,用于创建对象实例,而不会生成setter方法12。而@Data则会为类的所有属性生成setter方法,并且会生成一个无参构造器和一个全参构造器。
  • @Value和@Data都可以与其他注解一起使用,例如@Builder, @NoArgsConstructor, @AllArgsConstructor等,以实现更多的功能12。@Value还可以在注解后面加上括号和staticConstructor=”xxx”来指定一个静态工厂方法的名称,这样生成的全参构造器就会变成私有的,而静态工厂方法就会返回一个新的对象实例

2.9日志注解

Lombok日志注解是一种用于简化日志功能引入的注解,它可以让您在类上添加一个注解,就可以直接使用log对象来记录日志,而不需要声明和初始化日志对象。Lombok提供了多种日志注解,根据您使用的日志框架不同,您可以选择不同的注解。例如:

  • @Slf4j:用于生成一个名为log的org.slf4j.Logger对象,适用于SLF4J框架。
  • @Log4j:用于生成一个名为log的org.apache.log4j.Logger对象,适用于Log4j框架。
  • @Log4j2:用于生成一个名为log的org.apache.logging.log4j.Logger对象,适用于Log4j 2框架。
  • @CommonsLog:用于生成一个名为log的org.apache.commons.logging.Log对象,适用于Apache Commons Logging框架。
  • @JBossLog:用于生成一个名为log的org.jboss.logging.Logger对象,适用于JBoss Logging框架。
  • @Log:用于生成一个名为log的java.util.logging.Logger对象,适用于Java Util Logging框架。
  1. // 使用@Log4j注解声明一个Demo类
  2. import lombok.extern.log4j.Log4j;
  3. @Log4j
  4. public class Demo {
  5. public static void main(String[] args) {
  6. // 直接使用log对象记录日志
  7. log.info("Hello, Lombok!");
  8. log.error("Something went wrong!");
  9. }
  10. }
  11. // 使用@JBossLog注解声明一个Test类
  12. import lombok.extern.jbosslog.JBossLog;
  13. @JBossLog
  14. public class Test {
  15. public void doSomething() {
  16. // 直接使用log对象记录日志
  17. log.debug("Doing something...");
  18. log.warn("Be careful!");
  19. }
  20. }

发表评论

表情:
评论列表 (有 0 条评论,172人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Lombok-入门

    随着编程以及各种框架的发展,大大提供了开发的简洁和便利性。在开发过程中,我们经常要定义各种Bean,在Bean中会出现大量的getter、setter方法,有时还会重写toSt

    相关 Lombok简介

    最近发现了一个非常好用的库,叫做[Lombok][],它可以帮助我们简化一些Java代码的编写。我试用了一下感觉非常好用,所以来介绍一下。 下面对Lombok的简单使用方法做