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);
}
}