val
精简变量修饰,类似Scala,但是默认追加了final修饰符
val list = new ArrayList<String>();
//等同于
final ArrayList<String> list = new ArrayList<String>();
var
精简变量修饰,类似Scala,修饰变量
val list = new ArrayList<String>();
//等同于
ArrayList<String> list = new ArrayList<String>();
NonNull
修饰方法或者构造方法的参数,以及成员变量
public NonNullExample(@NonNull Person person) {
super("Hello");
this.name = person.getName();
}
//等同于
public NonNullExample(@NonNull Person person) {
super("Hello");
if (person == null) {
throw new NullPointerException("person is marked @NonNull but is null");
}
this.name = person.getName();
}
Cleanup
修饰局部变量,用于关闭资源
默认触发修饰变量的close
方法,但是如果目标对象没有close方法,可以直接指定关闭方法的名称
但是要求关闭方法不能有参数
@Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);
import lombok.Cleanup;
import java.io.*;
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);
}
}
}
等同于
import java.io.*;
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();
}
}
}
}
Getter/Setter
修饰成员变量或者类,已生成GetSet方法
- 当修饰类时,将生成类中所有的非静态成员变量的Get/Set类
- Getter/Setter都有
AccessLevel
参数,可设置生成的方法的修饰符(PUBLIC
,PROTECTED
,PACKAGE
, andPRIVATE
) - 如果类被注解修饰,但是某个成员变量不想生成方法,可以设置
AccessLevel
参数值为NONE
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
public class GetterSetterExample {
/**
* Age of the person. Water is wet.
*
* @param age New value for this person's age. Sky is blue.
* @return The current value of this person's age. Circles are round.
*/
@Getter @Setter private int age = 10;
/**
* Name of the person.
* -- SETTER --
* Changes the name of this person.
*
* @param name The new value.
*/
@Setter(AccessLevel.PROTECTED) private String name;
@Override public String toString() {
return String.format("%s (age: %d)", name, age);
}
}
等同于
public class GetterSetterExample {
/**
* Age of the person. Water is wet.
*/
private int age = 10;
/**
* Name of the person.
*/
private String name;
@Override public String toString() {
return String.format("%s (age: %d)", name, age);
}
/**
* Age of the person. Water is wet.
*
* @return The current value of this person's age. Circles are round.
*/
public int getAge() {
return age;
}
/**
* Age of the person. Water is wet.
*
* @param age New value for this person's age. Sky is blue.
*/
public void setAge(int age) {
this.age = age;
}
/**
* Changes the name of this person.
*
* @param name The new value.
*/
protected void setName(String name) {
this.name = name;
}
}
ToString
修饰类和方法,重写toString方法
- 默认格式
类名(字段值1,字段值2)
- 可通过设置includeFieldNames=true,在字段值前面加上
字段名:
- 默认所有非静态字段都会被打印,可以通过注解
@ToString.Exclude
来排除字段 - 如果只展示目标字段,可以在类的注解上追加参数
onlyExplicitlyIncluded=true
,然后在字段上加注解ToString.Include
- 如果需要打印父类的字段,可以设置参数
callSuper=true
- 打印方法的输出,在方法上追加注解
ToString.Include
,注意必须是非静态方法,并且没有参数
import lombok.ToString;
@ToString
public class ToStringExample {
private static final int STATIC_VAR = 10;
private String name;
private Shape shape = new Square(5, 10);
private String[] tags;
@ToString.Exclude private int id;
public String getName() {
return this.name;
}
@ToString(callSuper=true, includeFieldNames=true)
public static class Square extends Shape {
private final int width, height;
public Square(int width, int height) {
this.width = width;
this.height = height;
}
}
}
等同于
import java.util.Arrays;
public class ToStringExample {
private static final int STATIC_VAR = 10;
private String name;
private Shape shape = new Square(5, 10);
private String[] tags;
private int id;
public String getName() {
return this.name;
}
public static class Square extends Shape {
private final int width, height;
public Square(int width, int height) {
this.width = width;
this.height = height;
}
@Override public String toString() {
return "Square(super=" + super.toString() + ", width=" + this.width + ", height=" + this.height + ")";
}
}
@Override public String toString() {
return "ToStringExample(" + this.getName() + ", " + this.shape + ", " + Arrays.deepToString(this.tags) + ")";
}
}
EqualsAndHashCode
生成equals和hashCode方法
- 默认使用非静态和非
transient
修饰的字段 - 排除指定字段:注解
@EqualsAndHashCode.Exclude
- 只选择指定字段:类注解
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
,和字段注解@EqualsAndHashCode.Include
- 如果包含非Object父类,设置属性
callSuper=true
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class EqualsAndHashCodeExample {
private transient int transientVar = 10;
private String name;
private double score;
@EqualsAndHashCode.Exclude private Shape shape = new Square(5, 10);
private String[] tags;
@EqualsAndHashCode.Exclude private int id;
public String getName() {
return this.name;
}
@EqualsAndHashCode(callSuper=true)
public static class Square extends Shape {
private final int width, height;
public Square(int width, int height) {
this.width = width;
this.height = height;
}
}
}
等同于
import java.util.Arrays;
public class EqualsAndHashCodeExample {
private transient int transientVar = 10;
private String name;
private double score;
private Shape shape = new Square(5, 10);
private String[] tags;
private int id;
public String getName() {
return this.name;
}
@Override public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof EqualsAndHashCodeExample)) return false;
EqualsAndHashCodeExample other = (EqualsAndHashCodeExample) o;
if (!other.canEqual((Object)this)) return false;
if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
if (Double.compare(this.score, other.score) != 0) return false;
if (!Arrays.deepEquals(this.tags, other.tags)) return false;
return true;
}
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
final long temp1 = Double.doubleToLongBits(this.score);
result = (result*PRIME) + (this.name == null ? 43 : this.name.hashCode());
result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
result = (result*PRIME) + Arrays.deepHashCode(this.tags);
return result;
}
protected boolean canEqual(Object other) {
return other instanceof EqualsAndHashCodeExample;
}
public static class Square extends Shape {
private final int width, height;
public Square(int width, int height) {
this.width = width;
this.height = height;
}
@Override public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Square)) return false;
Square other = (Square) o;
if (!other.canEqual((Object)this)) return false;
if (!super.equals(o)) return false;
if (this.width != other.width) return false;
if (this.height != other.height) return false;
return true;
}
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
result = (result*PRIME) + super.hashCode();
result = (result*PRIME) + this.width;
result = (result*PRIME) + this.height;
return result;
}
protected boolean canEqual(Object other) {
return other instanceof Square;
}
}
}
@NoArgsConstructor
, @RequiredArgsConstructor
, @AllArgsConstructor
生成构造函数
NoArgsConstructor
注意有参数被final修饰的情况,需要加上参数(force = true)
RequiredArgsConstructor
只对两类变量有效,一种是final
修饰的并且没有初始化的变量,另外一类是NonNull
注解修饰并且没有初始化的变量AllArgsConstructor
生成一个包括所有参数的构造方法,并且有NonNull
注解的会进行非空检查@RequiredArgsConstructor(staticName="of")
生成一个私有的构造方法,并提供一个静态方法of包装私有构造方法- 以上注解只对非static字段生效
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.NonNull;
@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() {
}
}
}
Data
大集合
- 相当于一个快捷方式,包括之前的
toString
,EqualsAndHashCode
,所有字段的Getter
,非final字段的Setter
,和RequiredArgsConstructor
Data
无法像单个注解一样添加自定义属性,但是可以再次追加单个注解,以覆盖Data
对应的方法- 如果有任何同名的方法存在,
Data
不会再生成对应的方法 - 如果有任意一个构造方法,
Data
注解将不会生成RequiredArgsConstructor
对应的构造方法
import lombok.AccessLevel;
import lombok.Setter;
import lombok.Data;
import lombok.ToString;
@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;
}
}
等同于
import java.util.Arrays;
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
修饰类,生成一个final
类,并且成员变量全是private final
修饰
Value
是个快捷方式,完整的注解:final @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Getter
- 在修饰类和成员变量的同时,
Value
会生成toString
、equals
、hashCode
方法,还有包括所有参数的构造方法以及所有成员变量的get
方法 - 如果有任何自定义的构造方法,
Value
将不会再生成一个所有参数的构造方法
import lombok.AccessLevel;
import lombok.experimental.NonFinal;
import lombok.experimental.Value;
import lombok.experimental.Wither;
import lombok.ToString;
@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;
}
}
等同于
import java.util.Arrays;
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
构造者模式生成实体类,可修饰类,构造方法和一般方法
类似
Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();
- 当一个方法被
Builder
注解修饰(以下简称target),会有七个要素生成- 一个内部静态类叫做
FooBuilder
,有着和静态方法一样的类型参数(以下简称builder) - 在builder里,target方法的每一个参数都对应了一个私有的非静态非final的成员变量
- 在builder里,包含一个package范围的私有无参的空构造方法
- 在builder里,每一个target的参数都对应了一个类似
setter
的方法,但是这个setter
方法跟target方法的参数名一样,并且返回了builder自身,以形成链式结构 - 在builder里,包含一个
build
方法,用对应的参数调用target方法,最终生成target方法的返回值 - 在builder里,包含一个合理的
toString
实现 - 在target方法所在的类,会包含一个
builder
方法,他会创建类builder的实例
- 一个内部静态类叫做
- 以上的7个要素如果在检测到有同名的要素时会自动跳过(只对比名称)
- 当
Builder
作用于类时,请确保该类没有任何显性的构造函数。如果有任意显性构造函数,请直接将Builder
作用于构造函数上 - 当
Builder
和Value
同时作用于一个类时,Builder
想要生成的Package范围的构造函数会覆盖Value
想要生成的private范围的构造函数 - 如果参数的值需要从某个字段或者方法获取,可以在字段或者参数上添加注解
@Builder.ObtainVia(method = "")
Builder
可配置的方面包括- 静态内部类的名称(默认是type + “Builder”)
build
方法的名称builder
方法的名称- 是否需要toBuilder()方法
- 生成元素的访问范围
- 如果你的构造链方法需要一个前缀,比如
Person.builder().setName
- 关于以上配置项,下面是个实例
@Builder(builderClassName = "HelloWorldBuilder", buildMethodName = "execute", builderMethodName = "helloWorld", toBuilder = true, access = AccessLevel.PRIVATE, setterPrefix = "set")
- 当
Builder
注解作用于类,某些成员变量不需要set的时候,可以设置成员变量默认值
成员变量上用注解@Builder.Default
实现
@Builder.Default private final long created = System.currentTimeMillis();
@Singular
注解作用于参数或者成员变量时,会吧对应参数当做集合。- 不会生成
setter
而会生成两个adder
方法,一个新增单个,一个新增整个集合 - 还会生成一个
clear
方法,一旦build
方法被调用,生成的集合不能再被修改 - 可指定新增单个的方法名
@Singular("axis") List<Line> axes;
- 如果追加的集合为null会抛出异常,可设置忽略空集合
@Singular(ignoreNullCollections = true)
- 不会生成
import lombok.Builder;
import lombok.Singular;
import java.util.Set;
@Builder
public class BuilderExample {
@Builder.Default private long created = System.currentTimeMillis();
private String name;
private int age;
@Singular private Set<String> occupations;
}
等同于
import java.util.Set;
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 + ")";
}
}
}
SneakyThrows
checked Exception不用再try catch
不推荐
Synchronized
用户成员方法或者静态方法
关键字synchronized
锁的是this
,但是该注解锁的是不同的对象
import lombok.Synchronized;
public class SynchronizedExample {
private final Object readLock = new Object();
@Synchronized
public static void hello() {
System.out.println("world");
}
@Synchronized
public int answerToLife() {
return 42;
}
@Synchronized("readLock")
public void foo() {
System.out.println("bar");
}
}
等同于
public class SynchronizedExample {
private static final Object $LOCK = new Object[0];
private final Object $lock = new Object[0];
private final Object readLock = new Object();
public static void hello() {
synchronized($LOCK) {
System.out.println("world");
}
}
public int answerToLife() {
synchronized($lock) {
return 42;
}
}
public void foo() {
synchronized(readLock) {
System.out.println("bar");
}
}
}
With
用于成员变量或者类上,表示可修改类中的任何或者指定字段,即使该字段是final
其实就是clone了一个当前类,并修改对应成员变量的值
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.With;
public class WithExample {
@With(AccessLevel.PROTECTED) @NonNull private final String name;
@With private final int age;
public WithExample(String name, int age) {
if (name == null) throw new NullPointerException();
this.name = name;
this.age = age;
}
}
import lombok.NonNull;
public class WithExample {
private @NonNull final String name;
private final int age;
public WithExample(String name, int age) {
if (name == null) throw new NullPointerException();
this.name = name;
this.age = age;
}
protected WithExample withName(@NonNull String name) {
if (name == null) throw new java.lang.NullPointerException("name");
return this.name == name ? this : new WithExample(name, age);
}
public WithExample withAge(int age) {
return this.age == age ? this : new WithExample(name, age);
}
}
Getter(lazy=true)
修饰private final 成员变量,获取一次,并缓存,之后都取缓存
当一个成员变量的计算需要消耗大量资源,可以将它设置为private final,并加上该注解
这个注解会在第一次计算后缓存结果,他要求计算方法是非线程安全的
import lombok.Getter;
public class GetterLazyExample {
@Getter(lazy=true) private final double[] cached = expensive();
private double[] expensive() {
double[] result = new double[1000000];
for (int i = 0; i < result.length; i++) {
result[i] = Math.asin(i);
}
return result;
}
}
等同于
public class GetterLazyExample {
private final java.util.concurrent.AtomicReference<java.lang.Object> cached = new java.util.concurrent.AtomicReference<java.lang.Object>();
public double[] getCached() {
java.lang.Object value = this.cached.get();
if (value == null) {
synchronized(this.cached) {
value = this.cached.get();
if (value == null) {
final double[] actualValue = expensive();
value = actualValue == null ? this.cached : actualValue;
this.cached.set(value);
}
}
}
return (double[])(value == this.cached ? null : value);
}
private double[] expensive() {
double[] result = new double[1000000];
for (int i = 0; i < result.length; i++) {
result[i] = Math.asin(i);
}
return result;
}
}
Log
修饰类,增加成员变量log
多个注解,以适配多种Logger:
- @CommonsLog
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class); - @Flogger
private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass(); - @JBossLog private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
- @Log
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName()); - @Log4j
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class); - @Log4j2
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class); - @Slf4j
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class); - @XSlf4j
private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class); - @CustomLog
可自定义log,详情参考结尾的官方链接
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
@Log
public class LogExample {
public static void main(String... args) {
log.severe("Something's wrong here");
}
}
@Slf4j
public class LogExampleOther {
public static void main(String... args) {
log.error("Something else is wrong here");
}
}
@CommonsLog(topic="CounterLog")
public class LogExampleCategory {
public static void main(String... args) {
log.error("Calling the 'CounterLog' with a message");
}
}
相当于
public class LogExample {
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
public static void main(String... args) {
log.severe("Something's wrong here");
}
}
public class LogExampleOther {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class);
public static void main(String... args) {
log.error("Something else is wrong here");
}
}
public class LogExampleCategory {
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("CounterLog");
public static void main(String... args) {
log.error("Calling the 'CounterLog' with a message");
}
}
详细参考 lombok官方文档