lombok注解

lombok的基本注解使用
变量相关
val和var

lombok帮助java低级版本拥有jdk10的特性

在lombok 0.10引入

使用var作为任何局部变量声明的类型(即使在for语句中),该类型将从初始化表达式中推断出来(该类型推断中不涉及对变量的任何进一步赋值)。
例如:

var x=10.0; 将推断double;
var y=new arraylist(); 将推断Arraylist;

对于复合类型,推断出最常见的父类,而不是接口。

例如,bool ? new HashSet() : new ArrayList()是一个带有复合类型的表达式.
存在同样的父类:AbstractCollection,也实现了同样的接口:Serializable。
最终推断的类型将是AbstractCollection,因为它是一个类,而Serializable是接口。

在不明确的情况下,例如当初始化表达式是null,将推断为java.lang.Object

这是一个注释类型,因为var x=10;将被解语法糖为@var int x=10;

注意:var 和 val 具有完全相同的语义,只是val变成@val

但是推荐使用val,因为idea具有val自带的postfix template

//使用示例

public String example() {
    val example = new ArrayList<String>();
    example.add("Hello, World!");
    val foo = example.get(0);
    return foo.toLowerCase();
  }

提示如下:
ide提示
@NonNull

方法参数上

Lombok将在方法/构造函数体的开头插入一个空检查,并将参数的名称作为消息引发一个NullPointerException

字段上

任何为该字段赋值的生成方法也将生成这些空检查 @NonNull private T description;

//------------------
private ConstructorExample(T description) {
    if (description == null) throw new NullPointerException("description");
    this.description = description;
  }

实体类相关
@Getter and @Setter
基本说明

取代实体类中的get和set方法

Never write public int getFoo() {return foo;} again

可以在任何字段上使用@Getter或@Setter,lombok会自动生成默认的getter / setter

如果在类上使用,则所有字段生成getter / setter

AccessLevel:

可以通过AccessLevel重写访问级别

关于字段注释:

lombok v1.12.0中的新功能:将字段上的javadoc复制到生成的getter和setter。

方法命名

getter:
默认情况下方法名为:get+字段名以驼峰连接。
如果是boolean类型则:is+字段名以驼峰连接。(Boolean类型是get开头)

不建议使用is开头的字段命名,会产生混淆

String getName(){return name;}
boolean isHealth(){return health;}
setter:
setter不受boolean影响:set+字段名以驼峰连接。

一般使用

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

public class GetterSetterExample {

  @Getter @Setter private int age = 10;
  
  @Setter(AccessLevel.PROTECTED) private String name;
  
  @Override public String toString() {
    return String.format("%s (age: %d)", name, age);
  }
}

生成类:

 public class GetterSetterExample {

  private int age = 10;

  private String name;
  
  @Override public String toString() {
    return String.format("%s (age: %d)", name, age);
  }
  
  public int getAge() {
    return age;
  }
  
  public void setAge(int age) {
    this.age = age;
  }
  
  protected void setName(String name) {
    this.name = name;
  }
}

特殊事项

@Getter可用于枚举而@Setter不能
来自流行库的注释检查,例如javax.annotation.Nonnull,如果存在于字段上,导致生成的setter中会进行显式的空检查。
当与@Accessors注解一起使用会产生影响

@Accessors
基本说明

使用范围:类或字段上

目的是修改getter和setter方法的内容

在lombok v0.11.0中作为实验特征引入

功能

fluent

如果为true,那么getter 和setter 生成的方法名没有前缀。此外,除非指定,否则chain将为true。

chain

如果为true,则生成的setter返回this而不是void。默认值:false

prefix

如果存在,则字段必须以任何这些前缀为前缀。每个字段名称依次与列表中的每个前缀进行比较,如果找到匹配项,则会剥离前缀以创建字段的基本名称。在列表中包含一个空字符串是合法的它将始终匹配。

对于字母的字符,前缀后面的字符不能是小写字母,即以p为前缀也不会匹配pepper,但是pEpper会被匹配上(并且意味着该字段的基本名称epper)。

++如果提供了前缀列表并且字段不以其中一个字段开头,则lombok将完全跳过该字段,并将生成警告++

使用举例:

import lombok.experimental.Accessors;
import lombok.Getter;
import lombok.Setter;

@Accessors(fluent = true)
public class AccessorsExample {
  @Getter @Setter
  private int age = 10;
}

class PrefixExample {
  @Accessors(prefix = "f") @Getter
  private String fName = "Hello, World!";
}

  

等价于

 public class AccessorsExample {
  private int age = 10;
  
  public int age() {
    return this.age;
  }
  
  public AccessorsExample age(final int age) {
    this.age = age;
    return this;
  }
}

class PrefixExample {
  private String fName = "Hello, World!";
  
  public String getName() {
    return this.fName;
  }
}

@AllArgsConstructor和RequiredArgsConstructor和@NoArgsConstructor
简介

分别生成:全参构造方法,带参构造,无参构造
简单使用

@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {
  private int x, y;
  @NonNull private T description;
  
  @NoArgsConstructor
  public static class NoArgsExample {
    @NonNull private String field;
  }
}

等价于:

 public class ConstructorExample<T> {
  private int x, y;
  @NonNull private T description;
  
  private ConstructorExample(T description) {
    if (description == null) throw new NullPointerException("description");
    this.description = description;
  }
  
  public static <T> ConstructorExample<T> of(T description) {
    return new ConstructorExample<T>(description);
  }
  
  @java.beans.ConstructorProperties({"x", "y", "description"})
  protected ConstructorExample(int x, int y, T description) {
    if (description == null) throw new NullPointerException("description");
    this.x = x;
    this.y = y;
    this.description = description;
  }
  
  public static class NoArgsExample {
    @NonNull private String field;
    
    public NoArgsExample() {
    }
  }
}

@ToString和@EqualsAndHashCode

自动重写toString\equals\hashCode方法

具体可以看一下@Data
@Data
简介

作用范围: 类上

集成以下注解

@Getter
@Setter
@RequiredArgsConstructor
@ToString
@EqualsAndHashCode

独有属性配置:

staticConstructor 静态方法名

@Data(staticConstructor=“of”)
通过新的方式来创建实例:Foo.of(5)

使用

@Data
 public class DataExample {
  private final String name;
  @Setter(AccessLevel.PACKAGE) private int age;
  private double score;
  private String[] tags;
  
  @ToString(includeFieldNames=true)
  @Data(staticConstructor="of")
  public static class Exercise<T> {
    private final String name;
    private final T value;
  }
}

等价于:

public class DataExample {
  private final String name;
  private int age;
  private double score;
  private String[] tags;
  
  public DataExample(String name) {
    this.name = name;
  }
  
  public String getName() {
    return this.name;
  }
  
  void setAge(int age) {
    this.age = age;
  }
  
  public int getAge() {
    return this.age;
  }
  
  public void setScore(double score) {
    this.score = score;
  }
  
  public double getScore() {
    return this.score;
  }
  
  public String[] getTags() {
    return this.tags;
  }
  
  public void setTags(String[] tags) {
    this.tags = tags;
  }
  
  @Override public String toString() {
    return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() + ", " + Arrays.deepToString(this.getTags()) + ")";
  }
  
  protected boolean canEqual(Object other) {
    return other instanceof DataExample;
  }
  
  @Override public boolean equals(Object o) {
    if (o == this) return true;
    if (!(o instanceof DataExample)) return false;
    DataExample other = (DataExample) o;
    if (!other.canEqual((Object)this)) return false;
    if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
    if (this.getAge() != other.getAge()) return false;
    if (Double.compare(this.getScore(), other.getScore()) != 0) return false;
    if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
    return true;
  }
  
  @Override public int hashCode() {
    final int PRIME = 59;
    int result = 1;
    final long temp1 = Double.doubleToLongBits(this.getScore());
    result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
    result = (result*PRIME) + this.getAge();
    result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
    result = (result*PRIME) + Arrays.deepHashCode(this.getTags());
    return result;
  }
  
  public static class Exercise<T> {
    private final String name;
    private final T value;
        private Exercise(String name, T value) {
      this.name = name;
      this.value = value;
    }
        public static <T> Exercise<T> of(String name, T value) {
      return new Exercise<T>(name, value);
    }
    
   public String getName() {
      return this.name;
    }
        public T getValue() {
      return this.value;
    }
    
   @Override public String toString() {
      return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")";
    }
    
   protected boolean canEqual(Object other) {
      return other instanceof Exercise;
    }
        @Override public boolean equals(Object o) {
      if (o == this) return true;
      if (!(o instanceof Exercise)) return false;
      Exercise<?> other = (Exercise<?>) o;
      if (!other.canEqual((Object)this)) return false;
      if (this.getName() == null ? other.getValue() != null : !this.getName().equals(other.getName())) return false;
      if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false;
      return true;
    }
    
   @Override public int hashCode() {
      final int PRIME = 59;
      int result = 1;
      result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
      result = (result*PRIME) + (this.getValue() == null ? 43 : this.getValue().hashCode());
      return result;
    }
  }
}

@Value
说明

作用在类或字段上

@Value是不可变的@Data

@ToString,@EqualsAndHashCode,@AllArgsConstructor,@FieldDefaults,@Getter。

所有字段由private和final修饰,不会产生setter方法。类本身也是由final修饰。

使用举例

@Value public class ValueExample {
  String name;
  @Wither(AccessLevel.PACKAGE) @NonFinal int age;
  double score;
  protected String[] tags;
  
  @ToString(includeFieldNames=true)
  @Value(staticConstructor="of")
  public static class Exercise<T> {
    String name;
    T value;
  }
}

等价于:

public final class ValueExample {
  private final String name;
  private int age;
  private final double score;
  protected final String[] tags;
  
  @java.beans.ConstructorProperties({"name", "age", "score", "tags"})
  public ValueExample(String name, int age, double score, String[] tags) {
    this.name = name;
    this.age = age;
    this.score = score;
    this.tags = tags;
  }
  
  public String getName() {
    return this.name;
  }
  
  public int getAge() {
    return this.age;
  }
  
  public double getScore() {
    return this.score;
  }
  
  public String[] getTags() {
    return this.tags;
  }
  
  @java.lang.Override
  public boolean equals(Object o) {
    if (o == this) return true;
    if (!(o instanceof ValueExample)) return false;
    final ValueExample other = (ValueExample)o;
    final Object this$name = this.getName();
    final Object other$name = other.getName();
    if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
    if (this.getAge() != other.getAge()) return false;
    if (Double.compare(this.getScore(), other.getScore()) != 0) return false;
    if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
    return true;
  }
  
  @java.lang.Override
  public int hashCode() {
    final int PRIME = 59;
    int result = 1;
    final Object $name = this.getName();
    result = result * PRIME + ($name == null ? 43 : $name.hashCode());
    result = result * PRIME + this.getAge();
    final long $score = Double.doubleToLongBits(this.getScore());
    result = result * PRIME + (int)($score >>> 32 ^ $score);
    result = result * PRIME + Arrays.deepHashCode(this.getTags());
    return result;
  }
  
  @java.lang.Override
  public String toString() {
    return "ValueExample(name=" + getName() + ", age=" + getAge() + ", score=" + getScore() + ", tags=" + Arrays.deepToString(getTags()) + ")";
  }
  
  ValueExample withAge(int age) {
    return this.age == age ? this : new ValueExample(name, age, score, tags);
  }
  
  public static final class Exercise<T> {
    private final String name;
    private final T value;
        private Exercise(String name, T value) {
      this.name = name;
      this.value = value;
    }
        public static <T> Exercise<T> of(String name, T value) {
      return new Exercise<T>(name, value);
    }
       public String getName() {
      return this.name;
    }
    
   public T getValue() {
      return this.value;
    }
    
   @java.lang.Override
    public boolean equals(Object o) {
      if (o == this) return true;
      if (!(o instanceof ValueExample.Exercise)) return false;
      final Exercise<?> other = (Exercise<?>)o;
      final Object this$name = this.getName();
      final Object other$name = other.getName();
      if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
      final Object this$value = this.getValue();
      final Object other$value = other.getValue();
      if (this$value == null ? other$value != null : !this$value.equals(other$value)) return false;
      return true;
    }
    
   @java.lang.Override
    public int hashCode() {
      final int PRIME = 59;
      int result = 1;
      final Object $name = this.getName();
      result = result * PRIME + ($name == null ? 43 : $name.hashCode());
      final Object $value = this.getValue();
      result = result * PRIME + ($value == null ? 43 : $value.hashCode());
      return result;
    }
    
   @java.lang.Override
    public String toString() {
      return "ValueExample.Exercise(name=" + getName() + ", value=" + getValue() + ")";
    }
  }
}

@Builder和@Singular

自动生成构造者模式代码,Singular是针对集合属性的特殊处理。

@Singular
简介

@Singular对集合进行操作

最终会生成不可变集合

不可变集合:底层是可变集合,但是修改时会抛出异常

简单举例:

public class Person {
    @Singular private List<String> names;
}

//-------------生成的方法
name(String) 添加一个姓名(说白了就是把他从复数变成了单数)
clearNames() 清除
names(Collection<String>) 设置一个集合

代码中使用。

Person.builder().name(“小明”).name(“小红”).build()

注意事项

注意:Singular默认调用Collections.UnmodifiableCollection生成集合

配置useGuava=true后调用

guava的ImmutableXxx构建器

Singular原理

@Builder
public class SingularExample<T extends Number> {
  private @Singular Set<String> occupations;
  private @Singular("axis") ImmutableList<String> axes;
  private @Singular SortedMap<Integer, T> elves;
  private @Singular Collection<?> minutiae;
}

等价于:

import java.util.Collection;
import java.util.Set;
import java.util.SortedMap;
import com.google.common.collect.ImmutableList;

public class SingularExample<T extends Number> {
  private Set<String> occupations;
  private ImmutableList<String> axes;
  private SortedMap<Integer, T> elves;
  private Collection<?> minutiae;
  
  SingularExample(Set<String> occupations, ImmutableList<String> axes, SortedMap<Integer, T> elves, Collection<?> minutiae) {
    this.occupations = occupations;
    this.axes = axes;
    this.elves = elves;
    this.minutiae = minutiae;
  }
  
  public static class SingularExampleBuilder<T extends Number> {
    private java.util.ArrayList<String> occupations;
    private com.google.common.collect.ImmutableList.Builder<String> axes;
    private java.util.ArrayList<Integer> elves$key;
    private java.util.ArrayList<T> elves$value;
    private java.util.ArrayList<java.lang.Object> minutiae;
        SingularExampleBuilder() {
    }
    
   public SingularExampleBuilder<T> occupation(String occupation) {
      if (this.occupations == null) {
        this.occupations = new java.util.ArrayList<String>();
      }
           this.occupations.add(occupation);
      return this;
    }
       @java.lang.SuppressWarnings("all")
    public SingularExampleBuilder<T> occupations(java.util.Collection<? extends String> occupations) {
      if (this.occupations == null) {
        this.occupations = new java.util.ArrayList<String>();
      }
            this.occupations.addAll(occupations);
      return this;
    }
    
   public SingularExampleBuilder<T> axis(String axis) {
      if (this.axes == null) {
        this.axes = com.google.common.collect.ImmutableList.builder();
      }
          this.axes.add(axis);
      return this;
    }
    
   public SingularExampleBuilder<T> axes(java.lang.Iterable<? extends String> axes) {
      if (this.axes == null) {
        this.axes = com.google.common.collect.ImmutableList.builder();
      }
      
   this.axes.addAll(axes);
      return this;
    }
    
   public SingularExampleBuilder<T> elf(Integer elfKey, T elfValue) {
      if (this.elves$key == null) {
        this.elves$key = new java.util.ArrayList<Integer>();
        this.elves$value = new java.util.ArrayList<T>();
      }
      
   this.elves$key.add(elfKey);
      this.elves$value.add(elfValue);
      return this;
    }
    
   public SingularExampleBuilder<T> elves(java.util.Map<? extends Integer, ? extends T> elves) {
      if (this.elves$key == null) {
        this.elves$key = new java.util.ArrayList<Integer>();
        this.elves$value = new java.util.ArrayList<T>();
      }
      
   for (java.util.Map.Entry<? extends Integer, ? extends T> $lombokEntry : elves.entrySet()) {
        this.elves$key.add($lombokEntry.getKey());
        this.elves$value.add($lombokEntry.getValue());
      }
      return this;
    }
    
  public SingularExampleBuilder<T> minutia(java.lang.Object minutia) {
      if (this.minutiae == null) {
        this.minutiae = new java.util.ArrayList<java.lang.Object>();
      }
      
   this.minutiae.add(minutia);
      return this;
    }
        public SingularExampleBuilder<T> minutiae(java.util.Collection<?> minutiae) {
      if (this.minutiae == null) {
        this.minutiae = new java.util.ArrayList<java.lang.Object>();
      }
      
   this.minutiae.addAll(minutiae);
      return this;
    }
    
   public SingularExample<T> build() {
      java.util.Set<String> occupations;
      switch (this.occupations == null ? 0 : this.occupations.size()) {
      case 0: 
        occupations = java.util.Collections.emptySet();
        break;
      
   case 1: 
        occupations = java.util.Collections.singleton(this.occupations.get(0));
        break;
      
   default: 
        occupations = new java.util.LinkedHashSet<String>(this.occupations.size() < 1073741824 ? 1 + this.occupations.size() + (this.occupations.size() - 3) / 3 : java.lang.Integer.MAX_VALUE);
        occupations.addAll(this.occupations);
        occupations = java.util.Collections.unmodifiableSet(occupations);
      
      }
      
   com.google.common.collect.ImmutableList<String> axes = this.axes == null ? com.google.common.collect.ImmutableList.<String>of() : this.axes.build();
      
  java.util.SortedMap<Integer, T> elves = new java.util.TreeMap<Integer, T>();
      if (this.elves$key != null) for (int $i = 0; $i < (this.elves$key == null ? 0 : this.elves$key.size()); $i++) elves.put(this.elves$key.get($i), this.elves$value.get($i));
      elves = java.util.Collections.unmodifiableSortedMap(elves);
      
   java.util.Collection<java.lang.Object> minutiae;
      switch (this.minutiae == null ? 0 : this.minutiae.size()) {
      case 0: 
        minutiae = java.util.Collections.emptyList();
        break;
      
   case 1: 
        minutiae = java.util.Collections.singletonList(this.minutiae.get(0));
        break;
      
   default: 
        minutiae = java.util.Collections.unmodifiableList(new java.util.ArrayList<java.lang.Object>(this.minutiae));
      
   }
      
   return new SingularExample<T>(occupations, axes, elves, minutiae);
    }
       @java.lang.Override
    public java.lang.String toString() {
      return "SingularExample.SingularExampleBuilder(occupations=" + this.occupations + ", axes=" + this.axes + ", elves$key=" + this.elves$key + ", elves$value=" + this.elves$value + ", minutiae=" + this.minutiae + ")";
    }
  }
  
  @java.lang.SuppressWarnings("all")
  public static <T extends Number> SingularExampleBuilder<T> builder() {
    return new SingularExampleBuilder<T>();
  }
}

@Builder

通过内部类和一个全参构造器来实现构造者模式

复合举例:

@Builder
public class BuilderExample {
@Builder.Default private long created = System.currentTimeMillis();
private String name;
private int age;
@Singular private Set occupations;
}

等价于:

public class BuilderExample {
  private long created;
  private String name;
  private int age;
  private Set<String> occupations;
  
  BuilderExample(String name, int age, Set<String> occupations) {
    this.name = name;
    this.age = age;
    this.occupations = occupations;
  }
  
  private static long $default$created() {
    return System.currentTimeMillis();
  }
  
  public static BuilderExampleBuilder builder() {
    return new BuilderExampleBuilder();
  }
  
  public static class BuilderExampleBuilder {
    private long created;
    private boolean created$set;
    private String name;
    private int age;
    private java.util.ArrayList<String> occupations;
    
    BuilderExampleBuilder() {
    }
    
    public BuilderExampleBuilder created(long created) {
      this.created = created;
      this.created$set = true;
      return this;
    }
    
    public BuilderExampleBuilder name(String name) {
      this.name = name;
      return this;
    }
    
    public BuilderExampleBuilder age(int age) {
      this.age = age;
      return this;
    }
    
    public BuilderExampleBuilder occupation(String occupation) {
      if (this.occupations == null) {
        this.occupations = new java.util.ArrayList<String>();
      }
      
      this.occupations.add(occupation);
      return this;
    }
    
    public BuilderExampleBuilder occupations(Collection<? extends String> occupations) {
      if (this.occupations == null) {
        this.occupations = new java.util.ArrayList<String>();
      }

      this.occupations.addAll(occupations);
      return this;
    }
    
    public BuilderExampleBuilder clearOccupations() {
      if (this.occupations != null) {
        this.occupations.clear();
      }
      
      return this;
    }

    public BuilderExample build() {
      // complicated switch statement to produce a compact properly sized immutable set omitted.
      Set<String> occupations = ...;
      return new BuilderExample(created$set ? created : BuilderExample.$default$created(), name, age, occupations);
    }
    
    @java.lang.Override
    public String toString() {
      return "BuilderExample.BuilderExampleBuilder(created = " + this.created + ", name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")";
    }
  }
}

基本使用:

Person.builder().name(“Adam Savage”)
.city(“San Francisco”).job(“Mythbusters”)
.job(“Unchained Reaction”).build();

注意事项

由于Builder会生成一个全参构造器,导致默认的无参构造器失效,所以类采用@Builder注解后无法new出来。

完美的避免方式:

@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Person{}

加上@AllArgsConstructor、@NoArgsConstructor后就可以同时使用new和构造者方式实例化对象了

父类中的属性子类继承问题

简单解决方案是在子类中也手动写该属性

代码块
@Cleanup
简介

自动资源管理:自动调用关闭资源方法,默认是调用close()方法

在finally块中,只有在给定资源不是null的情况下才会调用清理方法

如果要清理的对象没有close()方法,可以指定一个无参方法来进行自动清理:

@Cleanup("dispose") CoolBar bar = new CoolBar(parent, 0);

基本使用

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    @Cleanup InputStream in = new FileInputStream(args[0]);
    @Cleanup OutputStream out = new FileOutputStream(args[1]);
    byte[] b = new byte[10000];
    while (true) {
      int r = in.read(b);
      if (r == -1) break;
      out.write(b, 0, r);
    }  }}

等价于

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    InputStream in = new FileInputStream(args[0]);
    try {
      OutputStream out = new FileOutputStream(args[1]);
      try {
        byte[] b = new byte[10000];
        while (true) {
          int r = in.read(b);
          if (r == -1) break;
          out.write(b, 0, r);
        }
      } finally {
        if (out != null) {
          out.close();
        }
      }
    } finally {
      if (in != null) {
        in.close();
      }
    }
  }
}

lombok的一些实验性注解:

位于lombok.experimental 包下,一些成熟的可能会转正

@ExtensionMethod : 可以扩展已有的类(不建议使用)

官方自己的说明
对代码风格的影响很大。
对于父类的扩展不能很好的应用到子类上。
在netbeans中不起作用。
@ExtensionMethod作用范围没有很好的定义
此功能比我们想象中有更多的错误。

@FieldDefaults (官方待转正)

作用在类上,不需要在每个字段上都加上private访问修饰符了

AccessLevel

给字段加上同样的访问修饰符

makeFinal

给字段加上final

使用示例:

@FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE)
public class FieldDefaultsExample {
  public final int a;
  int b;
  @NonFinal int c;
  @PackagePrivate int d;
  
  FieldDefaultsExample() {
    a = 0;
    b = 0;
    d = 0;
  }
}

等价于:

public class FieldDefaultsExample {
  public final int a;
  private final int b;
  private int c;
  final int d;
  
  FieldDefaultsExample() {
    a = 0;
    b = 0;
    d = 0;
  }
}

@Delegate (不建议使用)

生成委托对象的方法

types: 委托人
excludes: 被委托人

@Delegate(types=SimpleCollection.class)
则是说SimpleCollection的add和remove方法交给collection实现
这种方式最终只会生成SimpleCollection的两个方法
@Delegate(excludes=Add.class)
则是说collection的add和addAll方法由Add.class实现
这种方式最终会生成collection的全部方法

使用举例:

public class DelegationExample {
  private interface SimpleCollection {
    boolean add(String item);
    boolean remove(Object item);
  }
  
  @Delegate(types=SimpleCollection.class)
  private final Collection<String> collection = new ArrayList<String>();
}


class ExcludesDelegateExample {
  long counter = 0L;
  
  private interface Add {
    boolean add(String x);
    boolean addAll(Collection<? extends String> x);
  }
  
  @Delegate(excludes=Add.class)
  private final Collection<String> collection = new ArrayList<String>();
  
  public boolean add(String item) {
    counter++;
    return collection.add(item);
  }
  
  public boolean addAll(Collection<? extends String> col) {
    counter += col.size();
    return collection.addAll(col);
  }
}

等价于:

public class DelegationExample {
  private interface SimpleCollection {
    boolean add(String item);
    boolean remove(Object item);
  }
  
  private final Collection<String> collection = new ArrayList<String>();
  
  @java.lang.SuppressWarnings("all")
  public boolean add(final java.lang.String item) {
    return this.collection.add(item);
  }
  
  @java.lang.SuppressWarnings("all")
  public boolean remove(final java.lang.Object item) {
    return this.collection.remove(item);
  }
}

class ExcludesDelegateExample {
  long counter = 0L;
  
  private interface Add {
    boolean add(String x);
    boolean addAll(Collection<? extends String> x);
  }
  
  private final Collection<String> collection = new ArrayList<String>();
  
  public boolean add(String item) {
    counter++;
    return collection.add(item);
  }
  
  public boolean addAll(Collection<? extends String> col) {
    counter += col.size();
    return collection.addAll(col);
  }
  
  @java.lang.SuppressWarnings("all")
  public int size() {
    return this.collection.size();
  }
  
  @java.lang.SuppressWarnings("all")
  public boolean isEmpty() {
    return this.collection.isEmpty();
  }
  
  @java.lang.SuppressWarnings("all")
  public boolean contains(final java.lang.Object arg0) {
    return this.collection.contains(arg0);
  }
  
  @java.lang.SuppressWarnings("all")
  public java.util.Iterator<java.lang.String> iterator() {
    return this.collection.iterator();
  }
  
  @java.lang.SuppressWarnings("all")
  public java.lang.Object[] toArray() {
    return this.collection.toArray();
  }
  
  @java.lang.SuppressWarnings("all")
  public <T extends .java.lang.Object>T[] toArray(final T[] arg0) {
    return this.collection.<T>toArray(arg0);
  }
  
  @java.lang.SuppressWarnings("all")
  public boolean remove(final java.lang.Object arg0) {
    return this.collection.remove(arg0);
  }
  
  @java.lang.SuppressWarnings("all")
  public boolean containsAll(final java.util.Collection<?> arg0) {
    return this.collection.containsAll(arg0);
  }
  
  @java.lang.SuppressWarnings("all")
  public boolean removeAll(final java.util.Collection<?> arg0) {
    return this.collection.removeAll(arg0);
  }
  
  @java.lang.SuppressWarnings("all")
  public boolean retainAll(final java.util.Collection<?> arg0) {
    return this.collection.retainAll(arg0);
  }
  
  @java.lang.SuppressWarnings("all")
  public void clear() {
    this.collection.clear();
  }
}

@Wither(不推荐)

快速生成克隆类

举例:

public class WitherExample {
  @Wither private final int age;
  @Wither(AccessLevel.PROTECTED) @NonNull private final String name;
  
  public WitherExample(String name, int age) {
    if (name == null) throw new NullPointerException();
    this.name = name;
    this.age = age;
  }
}

等价于:

import lombok.NonNull;
public class WitherExample {
  private final int age;
  private @NonNull final String name;

  public WitherExample(String name, int age) {
    if (name == null) throw new NullPointerException();
    this.name = name;
    this.age = age;
  }

  public WitherExample withAge(int age) {
    return this.age == age ? this : new WitherExample(name, age);
  }

  protected WitherExample withName(@NonNull String name) {
    if (name == null) throw new java.lang.NullPointerException("name");
    return this.name == name ? this : new WitherExample(name, age);
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Lombok 是一个开源的Java库,它可以帮助Java开发人员减少Java代码的冗余并增加代码可读性。它通过注解的方式,自动为Java类生成一些常用的方法和代码。 以下是Java Lombok注解的一些常用的示例: @Data:该注解可以自动生成Java类的getter、setter、equals、hashCode、toString等方法。 @NoArgsConstructor:该注解可以自动生成一个无参构造函数。 @AllArgsConstructor:该注解可以自动生成一个包含所有参数的构造函数。 @Builder:该注解可以自动生成一个Builder模式的Java类。 @Slf4j:该注解可以自动生成一个名为log的slf4j日志对象。 @EqualsAndHashCode:该注解可以自动生成equals和hashCode方法。 @Getter / @Setter:该注解可以自动生成getter和setter方法。 @ToString:该注解可以自动生成toString方法。 @NonNull:该注解可以在参数前使用,表示该参数不能为空。 @RequiredArgsConstructor:该注解可以自动生成一个包含必需参数的构造函数。 @Cleanup:该注解可以自动关闭资源,如IO流等。 @Synchronized:该注解可以生成同步方法。 @Value:该注解可以生成一个不可变的Java类。 @Accessors:该注解可以设置getter和setter的链式调用方式。 @UtilityClass:该注解可以生成一个工具类。 总的来说,Java Lombok注解可以让Java开发人员更加专注于业务逻辑的实现,而不需要关心Java类的getter、setter、equals、hashCode、toString等方法的实现细节。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值