编者按
得益于JSR269 api标准,我们可以愉快地在编译期处理注解。
目录
一、 常用注解
二、 使用方法
一、常用注解
1.1 类构造
注解(位置TYPE)/属性 | staticName 私有化生产的构造器并生成一个静态构造方法 |
onConstructor 在生成的构造器上增加其他注解 |
access 设置生成的构造器的可见性 |
force 为true时,初始化所有静态属性到0/false/null |
---|---|---|---|---|
@AllArgsConstructor 生成一个全参构造器 |
√ | √ | √ | |
@RequiredArgsConstructor 生成一个必要参数构造器 |
√ | √ | √ | |
@NoArgsConstructor 生成一个空参构造器 |
√ | √ | √ | √ |
注解(位置) | 属性 |
---|---|
@Builder (TYPE,METHOD, CONSTRUCTOR) 生成目标类的一个建造者内部类 |
builderClassName:自定义建造类(TypeName)Builder的类名 builderMethodName:自定义builder()的方法名 buildMethodName:自定义build()的方法名 toBuilder: |
@Builder.ObtainVia (FIELD,PARAMETER) 注明一个参数或属性的获取方式 |
field:使用this.field赋值 method:使用this.method()赋值 isStatic:使用SelfType.method(this)赋值,要求mthod是静态的 |
@Builder.Default(FIELD) 注明一个属性有默认值 |
|
@Singular (FIELD,PARAMETER) 允许为集合类型的属性一项一项赋值 |
value:单项赋值方法的方法名 |
1.2 类属性
注解(位置) | 属性 |
---|---|
@Getter(TYPE,FIELD) 自动生成标准的getter方法 |
lazy:默认false,不可用 onMethod:在方法上增加其他注解 value:设置方法的可见性 |
@Setter(TYPE,FIELD) 自动生成标准的setter方法 |
onParam:在方法参数上增加其他注解 onMethod:同@Getter.onMethod value:同@Getter.value |
@Data(TYPE) @Getter/@Setter,@ToString, @EqualsAndHashCode和@RequiredArgsConstructor 组合的便捷写法 |
staticConstructor:同@RequiredArgsConstructor.staticName |
@EqualsAndHashCode(TYPE) 利用父类方法和相关属性生成equals()和hashCode() |
callSuper:在使用本类属性前先使用父类方法计算 doNotUseGetters:不使用getter方法 exclude:计算时不使用这里罗列的属性 of:计算时使用这里罗列的属性 onParam:同@Setter.onParam |
@ToString(TYPE) 利用父类方法和相关属性生成 |
callSuper:同@EqualsAndHashCode.callSuper doNotUseGetters:同@EqualsAndHashCode.doNotUseGetters exclude:同@EqualsAndHashCode.exclude of:同@EqualsAndHashCode.of includeFieldNames:是否打印属性名 |
1.3 日志
注解(位置TYPE) | 日志类类型 | 属性 |
---|---|---|
@CommonsLog | org.apache.commons.logging.Log | topic:自定义标题 |
@Log | java.util.logging.Logger | topic:同上 |
@JBossLog | org.jboss.logging.Logger | topic:同上 |
@Log4j | org.apache.log4j.Logger | topic:同上 |
@Log4j2 | org.apache.logging.log4j.Logger | topic:同上 |
@Slf4j | org.slf4j.Logger | topic:同上 |
@Slf4j2 | org.slf4j.ext.XLogger | topic:同上 |
关于日志上的注解,重点应该放在日志类型的选择上。一般情况下优先使用@Slf4j或@Slf4j2
1.4 杂项
注解(位置) | 属性 |
---|---|
@NonNull (FIELD,METHOD,PARAMETER,LOCAL_VARIABLE) 自动生成引用空检查代码,为空时抛出空指针异常 |
|
@SneakThrows(METHOD,CONSTRUCTOR) 自动生成代码,抛出受检异常 |
value:需要向上抛出的异常类型 |
@Synchronized(METHOD) 被标注的方法使用生成的锁对象($lock和$Lock)而非默认的(this和SlefType) |
value:使用指定的属性作为锁对象 |
@Value(TYPE) 便捷地转化可变类到不可变 |
staticConstructor:同@RequiredArgsConstructor.staticName |
@Cleanup(LOCAL_VARIABLE) 生成自动关闭资源的代码 |
value:使用指定的方法关闭资源,默认使用close() |
除了上述提到的注解和类,在lombok.experimental中还包含一些处于实验阶段中的注解(例如自动生成代理方法的@Delegate等)和类,这里不再描述。
二、使用方法
2.1 Javac
javac -cp lombok.jar ...
2.2 Maven
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
2.3 IntelliJ IDEA
- 菜单栏 :文件(File) > 设置(Setting) > 插件(Plugins)
- 点击:浏览仓库(Browse repositories...)
- 查找:Lombok Plugin
- 点击:安装插件(Install plugin)
- 重启软件
附
示例代码
1.1 类构造
// 原始代码
@AllArgsConstructor(
access = AccessLevel.PUBLIC,
onConstructor_ = {@SneakyThrows(Exception.class)})
@RequiredArgsConstructor(
access = AccessLevel.PROTECTED,
staticName = "ofRequiredArgs")
@NoArgsConstructor(
access = AccessLevel.PRIVATE,
force = true)
public class Example {
private final String privateFianlString;
private String privateString;
}
// 编译后
public class Example {
private final String privateFianlString;
private String privateString;
public Example(String privateFianlString, String privateString) {
try {
this.privateFianlString = privateFianlString;
this.privateString = privateString;
} catch (Exception var4) {
throw var4;
}
}
private Example(String privateFianlString) {
this.privateFianlString = privateFianlString;
}
protected static Example ofRequiredArgs(String privateFianlString) {
return new Example(privateFianlString);
}
private Example() {
this.privateFianlString = null;
}
}
// 原始代码
@Builder(
builderClassName = "ExampleBuilder2",
builderMethodName = "builder2",
buildMethodName = "build2",
toBuilder = true)
public class Example {
private static final String STRING = "defaultString2";
private String getDefaultString() { return STRING;}
private static String getDefaultString2() { return STRING;}
private final String fString;
@Builder.Default
private String string = "defaultString";
private String string2;
@Builder.ObtainVia(field = "STRING")
private String string3;
@Builder.ObtainVia(method = "getDefaultString")
private String string4;
@Builder.ObtainVia(method = "getDefaultString2", isStatic = true)
private String string5;
@Singular private List<String> listStrings;
@Singular("listString2e") private List<String> listString2s;
}
// 编译后
public class Example {
private static final String STRING = "defaultString2";
private final String fString;
private String string;
private String string2;
private String string3;
private String string4;
private String string5;
private List<String> listStrings;
private List<String> listString2s;
private String getDefaultString() {
return "defaultString2";
}
private static String getDefaultString2(Example example) {
return example.fString;
}
private static String $default$string() {
return "defaultString";
}
Example(String fString, String string, String string2, String string3, String string4, String string5, List<String> listStrings, List<String> listString2s) {
this.fString = fString;
this.string = string;
this.string2 = string2;
this.string3 = string3;
this.string4 = string4;
this.string5 = string5;
this.listStrings = listStrings;
this.listString2s = listString2s;
}
public static ExampleBuilder2 builder2() {
return new ExampleBuilder2();
}
public ExampleBuilder2 toBuilder() {
ExampleBuilder2 builder = (new ExampleBuilder2()).fString(this.fString).string(this.string).string2(this.string2).string3("defaultString2").string4(this.getDefaultString()).string5(getDefaultString2(this));
if (this.listStrings != null) {
builder.listStrings(this.listStrings);
}
if (this.listString2s != null) {
builder.listString2s(this.listString2s);
}
return builder;
}
}
public class Example$ExampleBuilder2 {
private String fString;
private boolean string$set;
private String string;
private String string2;
private String string3;
private String string4;
private String string5;
private ArrayList<String> listStrings;
private ArrayList<String> listString2s;
Example$ExampleBuilder2() {
}
public Example$ExampleBuilder2 fString(String fString) {
this.fString = fString;
return this;
}
public Example$ExampleBuilder2 string(String string) {
this.string = string;
this.string$set = true;
return this;
}
public Example$ExampleBuilder2 string2(String string2) {
this.string2 = string2;
return this;
}
public Example$ExampleBuilder2 string3(String string3) {
this.string3 = string3;
return this;
}
public Example$ExampleBuilder2 string4(String string4) {
this.string4 = string4;
return this;
}
public Example$ExampleBuilder2 string5(String string5) {
this.string5 = string5;
return this;
}
public Example$ExampleBuilder2 listString(String listString) {
if (this.listStrings == null) {
this.listStrings = new ArrayList();
}
this.listStrings.add(listString);
return this;
}
public Example$ExampleBuilder2 listStrings(Collection<? extends String> listStrings) {
if (this.listStrings == null) {
this.listStrings = new ArrayList();
}
this.listStrings.addAll(listStrings);
return this;
}
public Example$ExampleBuilder2 clearListStrings() {
if (this.listStrings != null) {
this.listStrings.clear();
}
return this;
}
public Example$ExampleBuilder2 listString2e(String listString2e) {
if (this.listString2s == null) {
this.listString2s = new ArrayList();
}
this.listString2s.add(listString2e);
return this;
}
public Example$ExampleBuilder2 listString2s(Collection<? extends String> listString2s) {
if (this.listString2s == null) {
this.listString2s = new ArrayList();
}
this.listString2s.addAll(listString2s);
return this;
}
public Example$ExampleBuilder2 clearListString2s() {
if (this.listString2s != null) {
this.listString2s.clear();
}
return this;
}
public Example build2() {
List listStrings;
switch(this.listStrings == null ? 0 : this.listStrings.size()) {
case 0:
listStrings = Collections.emptyList();
break;
case 1:
listStrings = Collections.singletonList(this.listStrings.get(0));
break;
default:
listStrings = Collections.unmodifiableList(new ArrayList(this.listStrings));
}
List listString2s;
switch(this.listString2s == null ? 0 : this.listString2s.size()) {
case 0:
listString2s = Collections.emptyList();
break;
case 1:
listString2s = Collections.singletonList(this.listString2s.get(0));
break;
default:
listString2s = Collections.unmodifiableList(new ArrayList(this.listString2s));
}
String string = this.string;
if (!this.string$set) {
string = Example.access$000();
}
return new Example(this.fString, string, this.string2, this.string3, this.string4, this.string5, listStrings, listString2s);
}
public String toString() {
return "Example.ExampleBuilder2(fString=" + this.fString + ", string=" + this.string + ", string2=" + this.string2 + ", string3=" + this.string3 + ", string4=" + this.string4 + ", string5=" + this.string5 + ", listStrings=" + this.listStrings + ", listString2s=" + this.listString2s + ")";
}
}
1.2 类属性
// 原始代码
@Setter(
value = AccessLevel.PRIVATE,
onParam_ = {@NonNull},
onMethod_ = {@Deprecated})
@EqualsAndHashCode(
callSuper = false,
doNotUseGetters = true,
exclude = {"string"},
onParam_ = {@NonNull})
@ToString(
callSuper = true,
doNotUseGetters = false,
of = {"string2"},
includeFieldNames = false)
public class Example {
@Getter(
value = AccessLevel.PUBLIC,
onMethod_ = {@Deprecated})
private String string;
@Getter( value = AccessLevel.PROTECTED)
private String string2;
private String string3;
}
// 编译后
public class Example {
private String string;
private String string2;
private String string3;
public Example() {
}
/** @deprecated */
@Deprecated
private void setString(@NonNull String string) {
if (string == null) {
throw new NullPointerException("string is marked @NonNull but is null");
} else {
this.string = string;
}
}
/** @deprecated */
@Deprecated
private void setString2(@NonNull String string2) {
if (string2 == null) {
throw new NullPointerException("string2 is marked @NonNull but is null");
} else {
this.string2 = string2;
}
}
/** @deprecated */
@Deprecated
private void setString3(@NonNull String string3) {
if (string3 == null) {
throw new NullPointerException("string3 is marked @NonNull but is null");
} else {
this.string3 = string3;
}
}
public boolean equals(@NonNull Object o) {
if (o == null) {
throw new NullPointerException("o is marked @NonNull but is null");
} else if (o == this) {
return true;
} else if (!(o instanceof Example)) {
return false;
} else {
Example other = (Example)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$string2 = this.string2;
Object other$string2 = other.string2;
if (this$string2 == null) {
if (other$string2 != null) {
return false;
}
} else if (!this$string2.equals(other$string2)) {
return false;
}
Object this$string3 = this.string3;
Object other$string3 = other.string3;
if (this$string3 == null) {
if (other$string3 != null) {
return false;
}
} else if (!this$string3.equals(other$string3)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(@NonNull Object other) {
return other instanceof Example;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $string2 = this.string2;
int result = result * 59 + ($string2 == null ? 43 : $string2.hashCode());
Object $string3 = this.string3;
result = result * 59 + ($string3 == null ? 43 : $string3.hashCode());
return result;
}
public String toString() {
return "Example(super=" + super.toString() + ", " + this.getString2() + ")";
}
/** @deprecated */
@Deprecated
public String getString() {
return this.string;
}
protected String getString2() {
return this.string2;
}
}
// 原始代码
@Data
public class Example {
private String string;
private String string2;
private String string3;
}
// 编译后
public class Example {
private String string;
private String string2;
private String string3;
public Example() {
}
public String getString() {
return this.string;
}
public String getString2() {
return this.string2;
}
public String getString3() {
return this.string3;
}
public void setString(String string) {
this.string = string;
}
public void setString2(String string2) {
this.string2 = string2;
}
public void setString3(String string3) {
this.string3 = string3;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Example)) {
return false;
} else {
Example other = (Example)o;
if (!other.canEqual(this)) {
return false;
} else {
label47: {
Object this$string = this.getString();
Object other$string = other.getString();
if (this$string == null) {
if (other$string == null) {
break label47;
}
} else if (this$string.equals(other$string)) {
break label47;
}
return false;
}
Object this$string2 = this.getString2();
Object other$string2 = other.getString2();
if (this$string2 == null) {
if (other$string2 != null) {
return false;
}
} else if (!this$string2.equals(other$string2)) {
return false;
}
Object this$string3 = this.getString3();
Object other$string3 = other.getString3();
if (this$string3 == null) {
if (other$string3 != null) {
return false;
}
} else if (!this$string3.equals(other$string3)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof Example;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $string = this.getString();
int result = result * 59 + ($string == null ? 43 : $string.hashCode());
Object $string2 = this.getString2();
result = result * 59 + ($string2 == null ? 43 : $string2.hashCode());
Object $string3 = this.getString3();
result = result * 59 + ($string3 == null ? 43 : $string3.hashCode());
return result;
}
public String toString() {
return "Example(string=" + this.getString() + ", string2=" + this.getString2() + ", string3=" + this.getString3() + ")";
}
}
1.3 日志
// 原始代码
@Log
public class Example { }
// 编译后
public class Example {
private static final Logger log = Logger.getLogger(Example.class.getName());
public Example() {
}
}
1.4 杂项
// 原始代码
@AllArgsConstructor(onConstructor_ = {@SneakyThrows})
@Value( staticConstructor = "of")
public class Example {
private Object f2Lock = new Object();
@NonNull
private String string;
private String string2;
private String string3;
@Synchronized @SneakyThrows({FileNotFoundException.class, MalformedURLException.class, IOException.class})
public void f(@NonNull String string) {
@Cleanup @NonNull
InputStream inputStream = new FileInputStream("");
}
@Synchronized("f2Lock") @NonNull
public void f2() {
System.out.println("Hello,World");
}
@Synchronized
public static void f3() {
System.out.println("Hello,World");
}
}
// 编译后
public final class Example {
private final Object $lock = new Object[0];
private static final Object $LOCK = new Object[0];
private final Object f2Lock = new Object();
@NonNull
private final String string;
private final String string2;
private final String string3;
public void f(@NonNull String string) {
try {
try {
try {
Object var2 = this.$lock;
synchronized(this.$lock) {
if (string == null) {
throw new NullPointerException("string is marked @NonNull but is null");
} else {
InputStream inputStream = new FileInputStream("");
if (Collections.singletonList(inputStream).get(0) != null) {
inputStream.close();
}
}
}
} catch (FileNotFoundException var6) {
throw var6;
}
} catch (MalformedURLException var7) {
throw var7;
}
} catch (IOException var8) {
throw var8;
}
}
@NonNull
public void f2() {
Object var1 = this.f2Lock;
synchronized(this.f2Lock) {
System.out.println("Hello,World");
}
}
public static void f3() {
Object var0 = $LOCK;
synchronized($LOCK) {
System.out.println("Hello,World");
}
}
public Object getF2Lock() {
return this.f2Lock;
}
@NonNull
public String getString() {
return this.string;
}
public String getString2() {
return this.string2;
}
public String getString3() {
return this.string3;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Example)) {
return false;
} else {
Example other;
label56: {
other = (Example)o;
Object this$f2Lock = this.getF2Lock();
Object other$f2Lock = other.getF2Lock();
if (this$f2Lock == null) {
if (other$f2Lock == null) {
break label56;
}
} else if (this$f2Lock.equals(other$f2Lock)) {
break label56;
}
return false;
}
label49: {
Object this$string = this.getString();
Object other$string = other.getString();
if (this$string == null) {
if (other$string == null) {
break label49;
}
} else if (this$string.equals(other$string)) {
break label49;
}
return false;
}
Object this$string2 = this.getString2();
Object other$string2 = other.getString2();
if (this$string2 == null) {
if (other$string2 != null) {
return false;
}
} else if (!this$string2.equals(other$string2)) {
return false;
}
Object this$string3 = this.getString3();
Object other$string3 = other.getString3();
if (this$string3 == null) {
if (other$string3 != null) {
return false;
}
} else if (!this$string3.equals(other$string3)) {
return false;
}
return true;
}
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $f2Lock = this.getF2Lock();
int result = result * 59 + ($f2Lock == null ? 43 : $f2Lock.hashCode());
Object $string = this.getString();
result = result * 59 + ($string == null ? 43 : $string.hashCode());
Object $string2 = this.getString2();
result = result * 59 + ($string2 == null ? 43 : $string2.hashCode());
Object $string3 = this.getString3();
result = result * 59 + ($string3 == null ? 43 : $string3.hashCode());
return result;
}
public String toString() {
return "Example(f2Lock=" + this.getF2Lock() + ", string=" + this.getString() + ", string2=" + this.getString2() + ", string3=" + this.getString3() + ")";
}
public Example(@NonNull String string, String string2, String string3) {
try {
if (string == null) {
throw new NullPointerException("string is marked @NonNull but is null");
} else {
this.string = string;
this.string2 = string2;
this.string3 = string3;
}
} catch (Throwable var5) {
throw var5;
}
}
}
// 原始代码
public class Example {
public static void main(String[] args) {
val list = Arrays.asList("123","234");
var list2 = Arrays.asList("123","234");
list2 = list;
}
}
// 编译后
public class Example {
public Example() {
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123", "234");
List<String> list2 = Arrays.asList("123", "234");
}
}