语法篇之Lombok简介

一、概述

1.1简介

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

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

1.2环境依赖


            org.projectlombok
            lombok
            1.18.18
            compile
        

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的,可以再次赋值,但必须与初始类型一致。

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

 缺点

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

2.2@NonNull

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

public void notNullExample(@NonNull String string) {
    string.length();
}
//=>相当于
public void notNullExample(String string) {
  if (string != null) {
      string.length();
  } else {
      throw new NullPointerException("null");
  }
}

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

@Data
public class User {
  @NonNull private String name;
  private Integer age;
}

 2.3@Cleanup

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

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

public static void main(String[] args) {
  try {
      @Cleanup InputStream inputStream = new FileInputStream(args[0]);
  } catch (FileNotFoundException e) {
      e.printStackTrace();
  }
  //=>相当于
  InputStream inputStream = null;
  try {
      inputStream = new FileInputStream(args[0]);
  } catch (FileNotFoundException e) {
      e.printStackTrace();
  } finally {
      if (inputStream != null) {
          try {
              inputStream.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
}

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

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

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

2.4@Getter/@Setter (常用)

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

@Setter(AccessLevel.PUBLIC)
@Getter(AccessLevel.PROTECTED)
private int id;
private String shap;

2.5@ToString(常用)

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

// 使用@ToString注解声明一个Account类
@ToString
public class Account {
  private String id;
  private String name;
  // standard getters and setters
}

// 创建一个Account对象并调用toString()方法
Account account = new Account();
account.setId("12345");
account.setName("An account");
System.out.println(account.toString());

// 输出结果如下:
Account(id=12345, name=An account)

 2.6构造函数(常用)

@NoArgsConstructor

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

// 使用@NoArgsConstructor注解声明一个User类
@NoArgsConstructor
public class User {
  private String name;
  private int age;
  // standard getters and setters
}

// 创建一个User对象并调用无参构造器
User user = new User();

 @RequiredArgsConstructor

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

// 使用@RequiredArgsConstructor注解声明一个Student类
@RequiredArgsConstructor
public class Student {
  private final String name;
  @NonNull private int age;
  // standard getters and setters
}

// 创建一个Student对象并调用带有参数的构造器
Student student = new Student("Alice", 20);

 @AllArgsConstructor

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

// 使用@AllArgsConstructor注解声明一个Person类
@AllArgsConstructor
public class Person {
  private String name;
  private int age;
  private String gender;
  // standard getters and setters
}

// 创建一个Person对象并调用带有所有参数的构造器
Person person = new Person("Bob", 25, "male");

 2.7@Data

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

  • 为类的所有属性生成getter和setter方法
  • 为类生成equals和hashCode方法,用于判断对象是否相等和计算哈希值
  • 为类生成toString方法,用于返回对象的字符串表示
  • 为类生成一个无参构造器和一个全参构造器,用于创建对象实例
  • 为类生成canEqual方法,用于判断其他对象是否可以与当前对象比较
// 使用@Data注解声明一个User类
@Data
public class User {
  private String name;
  private int age;
}

// 创建一个User对象并调用相关方法
User user = new User();
user.setName("Alice");
user.setAge(20);
System.out.println(user.getName()); // Alice
System.out.println(user.getAge()); // 20
System.out.println(user.toString()); // User(name=Alice, age=20)
System.out.println(user.hashCode()); // 2129789493
User user2 = new User();
user2.setName("Alice");
user2.setAge(20);
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框架。
// 使用@Log4j注解声明一个Demo类
import lombok.extern.log4j.Log4j;
@Log4j
public class Demo {
  public static void main(String[] args) {
    // 直接使用log对象记录日志
    log.info("Hello, Lombok!");
    log.error("Something went wrong!");
  }
}
// 使用@JBossLog注解声明一个Test类
import lombok.extern.jbosslog.JBossLog;
@JBossLog
public class Test {
  public void doSomething() {
    // 直接使用log对象记录日志
    log.debug("Doing something...");
    log.warn("Be careful!");
  }
}

你可能感兴趣的:(java,开发语言)