【java学习】Lombok学习(IDEA插件)

1,场景

编译源代码时自动生成 get/set/hashCode/equals/toString 等方法。

2,原理

Lombok这款插件正是依靠可插件化的Java自定义注解处理API(JSR 269: Pluggable Annotation Processing API)来实现在Javac编译阶段利用“Annotation Processor”对自定义的注解进行预处理后生成真正在JVM上面执行的“Class文件”。

3,使用

  1. idea安装插件
  2. 导入依赖
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.8</version>
</dependency>

4,常用注解

注解场景说明备注
@Data包含注解的集合@ToString,@EqualsAndHashCode,所有字段的@Getter和所有非final字段的@Setter, @RequiredArgsConstructor。其示例代码可以参考上面几个注解的组合。
@NonNull为方法或构造函数的参数提供非空检查
@Cleanup自动释放资源
Getter/@Setter针对类的属性字段自动生成Get/Set方法。设置在属性字段之前
@NoArgsConstructor生成无参构造器
@RequiredArgsConstructor生成指定参数构造器@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor生成所有参数构造器@AllArgsConstructor(access = AccessLevel.PROTECTED)
@ToString为使用该注解的类生成一个toString方法默认的toString格式为:ClassName(fieldName= fieleValue ,fieldName1=fieleValue)
@EqualsAndHashCode为使用该注解的类自动生成equals和hashCode方法
@Builder提供构建值对象的方式不可处理父类属性
@Synchronized类似Java中的Synchronized 关键字,但是可以隐藏同步锁
@Accessors(chain = true)开启链式调用

1)val

将变量申明是final类型。

public   static void main(String[] args) {
    val setVar = new HashSet<String>();
    val listsVar = new   ArrayList<String>();
    val mapVar = new HashMap<String,   String>();

    //=>上面代码相当于如下:
    final Set<String> setVar2 = new   HashSet<>();
    final List<String> listsVar2 = new   ArrayList<>();
    final Map<String, String> maps2 =   new HashMap<>();
}

2)@NonNull

为方法或构造函数的参数提供非空检查。

public void notNullExample(@NonNull String string) {
    //方法内的代码
}

//=>上面代码相当于如下:

public void notNullExample(String string) {
    if (string != null) {
        //方法内的代码相当于如下:
    } else {
        throw new NullPointerException("null");
    }
}

3)@Cleanup

自动释放资源。

public   void jedisExample(String[] args) {
    try {
        @Cleanup Jedis jedis =   redisService.getJedis();
    } catch (Exception ex) {
        logger.error(Jedis异常:,ex)
    }

    //=>上面代码相当于如下:
    Jedis jedis= null;
    try {
        jedis = redisService.getJedis();
    } catch (Exception e) {
        logger.error(Jedis异常:,ex)
    } finally {
        if (jedis != null) {
            try {
                jedis.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

4)@ToString

为使用该注解的类生成一个toString方法,默认的toString格式为:ClassName(fieldName= fieleValue ,fieldName1=fieleValue)。

@ToString(callSuper=true,exclude="someExcludedField")
public   class Demo extends Bar {

    private boolean someBoolean = true;
    private String someStringField;
    private float someExcludedField;

}

//上面代码相当于如下:

public   class Demo extends Bar {

    private boolean someBoolean = true;
    private String someStringField;
    private float someExcludedField;
   
    @ Override
    public String toString() {
        return "Foo(super=" +   super.toString() +
            ", someBoolean=" +   someBoolean +
            ", someStringField=" +   someStringField + ")";
    }
}

5)@EqualsAndHashCode

为使用该注解的类自动生成equals和hashCode方法。

@EqualsAndHashCode(exclude = {"id"}, callSuper =true)
public class LombokDemo extends Demo{
    private int id;
    private String name;
    private String gender;
}

//上面代码相当于如下:

public class LombokDemo extends Demo{

    private int id;
    private String name;
    private String gender;
    
    @Override
    public boolean equals(final Object o) {
        if (o == this) return true;
        if (o == null) return false;
        if (o.getClass() != this.getClass()) return false;
        if (!super.equals(o)) return false;
        final LombokDemo other = (LombokDemo)o;
        if (this.name == null ? other.name != null : !this.name.equals(other.name)) return false;
        if (this.gender == null ? other.gender != null : !this.gender.equals(other.gender)) return false;
        return true;
    }

    @Override
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = result * PRIME + super.hashCode();
        result = result * PRIME + (this.name == null ? 0 : this.name.hashCode());
        result = result * PRIME + (this.gender == null ? 0 : this.gender.hashCode());
        return result;
    }

}

默认情况下会使用非静态和非transient型字段来生成,但是你也通过在字段上添加 @EqualsAndHashCode.Include 或者@EqualsAndHashCode.Exclude 修改你使用的字段(甚至指定各种方法的输出)。或者你也可以通过在类上使用 @EqualsAndHashCode(onlyExplicitlyIncluded = true) ,且在特定字段或特定方法上添加 @EqualsAndHashCode.Include 来指定他们。

如果将@EqualsAndHashCode添加到继承于另一个类的类上,这个功能会有点棘手。一般情况下,为这样的类自动生成equals和hashCode方法是一个坏思路,因为超类也有定义了一些字段,他们也需要equals/hashCode方法但是不会自动生成。通过设置callSuper=true,可以在生成的equals和hashCode方法里包含超类的方法。对于hashCode,·super.hashCode()·会被包含在hash算法内,而对于equals,如果超类实现认为它与传入的对象不一致则会返回false。注意:并非所有的equals都能正确的处理这样的情况。然而刚好lombok可以,若超类也使用lombok来生成equals方法,那么你可以安全的使用它的equals方法。如果你有一个明确的超类, 你得在callSuper上提供一些值来表示你已经斟酌过,要不然的话就会产生一条警告信息。

当你的类没有继承至任何类(非java.lang.Object, 当然任何类都是继承于Object类的),而你却将callSuer置为true, 这会产生编译错误(译者注: java: Generating equals/hashCode with a supercall to java.lang.Object is pointless. )。因为这会使得生成的equals和hashCode方法实现只是简单的继承至Object类的方法,只有相同的对象并且相同的hashCode才会判定他们相等。若你的类继承至另一个类又没有设置callSuper, 则会产品一个告警,因为除非超类没有(或者没有跟相等相关的)字段,否则lombok无法为你生成考虑超类声明字段的实现。

6)@Builder

提供构建值对象的方式。

@Builder 
@AllArgsConstructor //联合使用
public class BuilderExample { 

  private String name; 
  private int age; 
}
BuilderExample example = BuilderExample.builder()
                .name("aaa")
                .age(1)
                .build();

//上面代码相当于如下:
public class BuilderExample { 

  private String name; 
  private int age; 

  BuilderExample(String name, int age) { 
    this.name = name; 
    this.age = age; 
  } 

  public static BuilderExampleBuilder builder() { 
    return new BuilderExampleBuilder(); 
  } 

  public static class BuilderExampleBuilder { 

    private String name; 
    private int age; 
    BuilderExampleBuilder() { 
    } 

    public BuilderExampleBuilder name(String name) { 
      this.name = name; 
      return this; 
    } 

    public BuilderExampleBuilder age(int age) { 
      this.age = age; 
      return this; 
    } 

    public BuilderExample build() {  
      Set<String> occupations = new HashSet<>(); 
      return new BuilderExample(name, age, occupations); 
    } 

    @verride 
    public String toString() { 
      return "BuilderExample.BuilderExampleBuilder(name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")"; 
    } 
  } 
}

7)@Synchronized

类似Java中的Synchronized 关键字,但是可以隐藏同步锁。

@Synchronized 
 public static void hello() { 
     System.out.println("world");   
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值