Lombok——代码简化

蜗牛旅行1899 / 2024-04-21 / 原文

lombok是一个简化代码的类库,可以使Java代码看起来更简洁,本质是在编译阶段会根据注解生成一些代码。

搭建环境比较简单,

第一步,引入lombok的Jar包。

第二步,在IDE上安装插件,例如idea的插件库直接搜索lombok即可。

它的注解,按照阶段分为两类,stable(稳定版), experimental(测试版),本文只介绍稳定版本。

根据功能划分为两类,添加在类上,简化类的注解。添加在方法上,简化方法的注解。

1、类

1.1  实体Bean

  1.1.1  getter & setter

  描述:为实体Bean添加getter和setter方法。

  原理:

      编译前代码:

@Getter 
private String name

     编译后代码:

public String getName(){ 
  return this.name
};

  注解属性:

    AccessLevel:get&set方法的修饰符,默认为public,可选值有private, public, protected, package, none。当为none时,不会生成get和set方法,最典型的就是序列化ID。

  场景:使用频率非常高,添加在实体bean上,忽略序列化ID。

  示例:略

  1.1.2  toString

  描述:生成toString方法。默认的格式为”类名(fieldname=fieldValue)”,拥有多个字段,会有多组fieldname=fieldValue。

  原理:

    编译前代码: 

@ToString
public class Test { 
	private String name;
}

    生成代码:

public String toString(){
	return "Test(name=" + this.name +")"; 
}

  注解属性:

    @ToString.Exclude:添加在字段上时,不包含该字段。

    onlyExplicitlyIncluded:默认情况下toString会包含所有字段,并排除掉@ToString.Exclude,设置该属性之后,toString只会包含@ToString.include的字段。

    @ToString.include:包含该字段。

  场景:频率较低,主流方式是将对象转换为JSON字符串。

  示例:略

1.1.3  equalAndHashCode

  描述:生成equals和hashCode方法。

  原理:略。

  注解属性:与@ToString类似,包含或排除某个字段。略。

  场景:频率较低。

  示例:略。

1.1.4  xxConstructor

  描述:生成构造器,有三种,

  @NoArgsConstructor:无参注解

  @RequiredArgsConstructor:有部分字段作为参数的构造器。

  @AllArgsConstructor:有所有字段作为参数的构造器。

原理:

注解属性:

场景:

示例:

1.1.5  data

描述:@Getter,@Setter,@EqualAndHashCode, @RequiredArgsConstructor的总和。

原理:略。

注解属性:略。

场景:略。

示例:略。

1.1.6  value

  描述:与@data注解相似,区别在于生成不可变类,所有字段添加final修饰符,不生成set方法。

  原理:略。

  注解属性:

    @NonFinal:在字段上添加@NonFinal,生成时,不会添加final修饰符。

  场景:略。

  示例:略。

  1.1.7  with

  描述:生成一个withXX方法根据字段进行比较,若字段值相同,返回当前对象,字段值不同,新创建一个对象,参数为该字段值。

  原理:

    编译前代码: 

@With 
private String name;

    生成代码:

public User withName(String name){
   return this.name == name ? this : new User(name);
}

  注解属性:

    AccessLevel:与getter&setter注解中的同名属性含义想相同,此处指定withXX方法的修饰符。

  场景:略。

  示例:略。

  1.1.8  builder

  描述:用构造器模式的方式生成相关的方法。例如User对象,

User user = User.builder()

.age(xx) // 年龄

.name(xx) // 姓名

.address(xx); // 地址。

  原理:略。

  注解属性:

      @Builder.Default:无需指定,自动生成的,例如new Date()。

      @Singular:在集合属性上添加。生成的方法会有不同。

  场景:若写builder方法,通常还需要添加一些逻辑,不会像set方法那样简单,实际使用频率较低。

  示例:略。

1.2  公共属性

  为对象添加一个常用的,公共的对象实例,例如,最常见的log。

  1.2.1  Log

  描述:为对象添加一个公共属性log。不同注解添加的log类型不同。

@commonLog: org.apache.commons.logging.Log

@Flogger:  com.google.common.flogger.FluentLogger

@JBossLog: org.jboss.logging.Logger

@Log: java.util.Logging.Logger

@Log4j: org.apache.log4j.log

@Log4j2: org.apache.logging.log4j.Logger

@Slf4j: org.slf4j.Logger

@CustomLog:org.apache.commons.logging.LogFactory.getLog("CounterLog")

1.2.2  Locked

  描述:在方法上添加锁的注解,生成一个锁的实例对象。有三种类型注解

  @Locked:创建ReentrantLock实例。

  @Locked.read 或 @Locked.write:创建ReentrantReadWriteLock实例。

  原理:

    编译前代码: 

@Locked("baseLock")
public void test() {
	System.out.println("hello Java");
}

    生成代码:

private final Lock baseLock = new ReentrantLock();
public void foo() {
	this.baseLock.lock();
	try {
	  System.out.println("bar");
	} finally {
	  this.baseLock.unlock();
	}
}

  注解属性:

    value:指定属性的名称。

场景:略。

示例:略。

1.2.3  synchronized

  描述:在方法上添加该注解,会生成一个公共属性$lock或$LOCK。

  在实例方法上添加此注解时,会自动生成$lock属性,并synchronized该字段。

  在静态方法上添加此注解时,会自动生成$LOCK属性,并synchronized该字段。

  原理:

    编译前代码: 

@synchronized
public void test(){};

    生成代码:

private final Object $lock = new Object[0];
public void test{
	synchronized($lock){
		// 代码块
	}
}

  注解属性:

    value:指定属性的名称。例如@synchronized(“syncProp”),公共属性名称从$lock或$LOCK替换为syncProp。

  场景:略。

  示例:略。

2、方法

2.1  公共

2.1.1  sneakyThrows

  描述:方法上无需声明显示异常。

  原理:

    编译前代码: 

@SneakyThrows("IOException")
public void test(){};

    生成代码:

public void test(){
	try{
        // test代码块。
	}catch(IOException e){
		throw Lombok.sneakyThrow(e);
	}
}

  注解属性:无。

  场景:IO操作方法时比较多。

  示例:略。

2.2  变量

  2.2.1  var & val

  描述:定义变量,无需指定具体类型,类似于JS。

  原理:

    编译前代码: 

var str = new String();

    生成代码:

String str = new String();

  注解属性:无。

  场景:通常变量名根据类型生成,反而不方便。

  示例:var user = new User();

  val注解和它是相似的,唯一的区别在于生成的变量带有final修饰符。

  2.2.2  cleanup

  描述:添加在变量上,生成finally方法,调用变量的close方法。

  原理:

    编译前代码: 

@CleanUp 
Connection conn = new Connection();

    生成代码: 

Connection conn = new Connection();
try{
	// new Connection的后续代码
}finally{
	if(conn!=null){
		conn.close();
	}
}

  注解属性:

    value:指定方法的名称,例如@CleanUp(“destory”),会调用destory方法。

  场景:没有try, catch,代码简洁很多。

  示例:@CleanUp InputStream input = new FileInputStream(“fileName”)

2.3  参数

  2.3.1  nonNull

  描述:判断参数非空。

  原理:

    编译前代码: 

public void test(@NonNull String name)

    生成代码: 

public void test(String name){
  if(name == null){
	      throw new NullPointerException(“name is marked non-null but is  null”)
  }
  // test方法的后续代码
}

  注解属性:略。

  场景:影响代码的阅读,通常不会使用。

  示例:略。