Lombok简介
Project Lombok makes java a spicier language by adding ‘handlers’ that know >how to build and compile simple, boilerplate-free, not-quite-java code.
github上官方是这么描述lombok的:
lombok项目通过增加处理程序使我们的java语言更加刺激(简洁和快速)。
先看个简单示例:
我们做java开发的时候,最不少写的就是javabean了,bean字段都需要添加gettter/setter方法,往往我们只能一次又一次的使用ide生成gettter,setter 构造器等等。
lombok是如何帮我们解决这种重复性劳动呢?
-
package com.lhy.boot.lombok;
-
-
import lombok.Getter;
-
import lombok.Setter;
-
-
@Getter
-
@Setter
-
public
class GetterSetterExample1 {
-
-
private
int age =
10;
-
-
private String name =
"张三丰";
-
-
private
boolean registerd;
-
-
private String sex;
-
-
}
编译后的class:
-
package com.lhy.boot.lombok;
-
-
public
class GetterSetterExample1
-
{
-
private
int age =
10;
-
-
private String name =
"张三丰";
-
private
boolean registerd;
-
private String sex;
-
-
public int getAge()
-
{
-
return
this.age;
-
}
-
-
public String getName() {
-
return
this.name;
-
}
-
-
public boolean isRegisterd() {
-
return
this.registerd;
-
}
-
-
public String getSex() {
-
return
this.sex;
-
}
-
-
public GetterSetterExample1 setAge(int age) {
-
this.age = age;
-
return
this;
-
}
-
-
public GetterSetterExample1 setName(String name) {
-
this.name = name;
-
return
this;
-
}
-
-
public GetterSetterExample1 setRegisterd(boolean registerd) {
-
this.registerd = registerd;
-
return
this;
-
}
-
-
public GetterSetterExample1 setSex(String sex) {
-
this.sex = sex;
-
return
this;
-
}
-
}
通过gettter,setter注解lombok已经帮我们自动生成了getter,setter方法!
是不是很神奇呢?lombok是怎么的做到的?这个后边再讲,先把lombok ide插件环境搭起来
下载并引用
maven项目添加依赖
-
<dependency>
-
<groupId>org.projectlombok
</groupId>
-
<artifactId>lombok
</artifactId>
-
<version>1.16.16
</version>
-
</dependency>
或者到官网下载jar包 https://projectlombok.org/download
安装ide插件
myeclipse/eclipse
下载完成后 命令行运行
java -jar lombok-1.16.16.jar
弹出安装界面:
specify location 选择myeclipse安装目录,eclipse同理。
点击 install/update 安装完成。
或者将jar包放入myeclipse 根目录下
myeclipse.ini文件末尾添加:
-javaagent:lombok-1.16.16.jar
重启myeclipse即可。
安装完毕后
打开myeclipse about 可以看到
证明插件安装完成
IntelliJ IDEA
- 定位到 File > Settings > Plugins
- 点击 Browse repositories…
- 搜索 Lombok Plugin
- 点击 Install plugin
- 重启 IDEA
Lombok注解详解
全局配置文件
Lombok通常为所有生成的节点生成注释,添加@javax.annotation.Generated 。
可以用:
lombok.addJavaxGeneratedAnnotation = false 设置取消
下面看下lombok提供了哪些有趣的注解。
1.@val @var
使用Lombok ,java也能够像javascript一样使用弱类型定义变量了
val注解变量申明是final类型 var注解变量是非final类型
-
import java.util.ArrayList;
-
import java.util.HashMap;
-
import lombok.val;
-
-
public
class ValExample {
-
public String example() {
-
val example =
new ArrayList<String>();
-
example.add(
"Hello, World!");
-
val foo = example.get(
0);
-
return foo.toLowerCase();
-
}
-
-
public void example2() {
-
val map =
new HashMap<Integer, String>();
-
map.put(
0,
"zero");
-
map.put(
5,
"five");
-
for (val entry : map.entrySet()) {
-
System.out.printf(
"%d: %s\n", entry.getKey(), entry.getValue());
-
}
-
}
-
}
翻译后
-
import java.util.ArrayList;
-
import java.util.HashMap;
-
import java.util.Map;
-
-
public
class ValExample {
-
public String example() {
-
final ArrayList<String> example =
new ArrayList<String>();
-
example.add(
"Hello, World!");
-
final String foo = example.get(
0);
-
return foo.toLowerCase();
-
}
-
-
public void example2() {
-
final HashMap<Integer, String> map =
new HashMap<Integer, String>();
-
map.put(
0,
"zero");
-
map.put(
5,
"five");
-
for (
final Map.Entry<Integer, String> entry : map.entrySet()) {
-
System.out.printf(
"%d: %s\n", entry.getKey(), entry.getValue());
-
}
-
}
-
}
2.@NonNull
在方法或构造函数的参数上使用@NonNull,lombok将生成一个空值检查语句。
-
import lombok.NonNull;
-
-
public
class NonNullExample extends Something {
-
private String name;
-
-
public NonNullExample(@NonNull Person person) {
-
super(
"Hello");
-
this.name = person.getName();
-
}
-
}
翻译后
-
import lombok.NonNull;
-
-
public
class NonNullExample extends Something {
-
private String name;
-
-
public NonNullExample(@NonNull Person person) {
-
super(
"Hello");
-
if (person ==
null) {
-
throw
new NullPointerException(
"person");
-
}
-
this.name = person.getName();
-
}
-
}
3.@Cleanup
使用该注解能够自动释放io资源
-
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();
-
}
-
}
-
}
-
}
当然从1.7开始jdk已经提供了try with resources的方式自动回收资源
-
static String readFirstLineFromFile(String path) throws IOException {
-
try (BufferedReader br =
new BufferedReader(
new FileReader(path))) {
-
return br.readLine();
-
}
-
}
4.@Getter/@Setter
-
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;
-
}
-
}
扩展配置:
lombok.accessors.chain
= [
true
|
false
] (default: false)如果设置为true,生成的setter将返回this(而不是void),通过这个配置我们可以像jquery一样愉快的链式编程了。可以在类加增加一个@Accessors 注解 配置chain属性,优先于全局配置。
lombok.accessors.fluent
= [
true
|
false
] (default: false)如果设置为true,生成的getter和setter将不会使用bean标准的get、is或set进行前缀;相反,方法将使用与字段相同的名称(减去前缀)。可以在类加增加一个@Accessors注解,配置fluent属性,优先于全局配置
lombok.accessors.prefix
+=
a field prefix (default: empty list)
给getter/setter方法增加前缀 例如配置 +=M 原有的 getFoo方法将变为getMFoo方法。
lombok.getter.noIsPrefix
= [
true
|
false
] (default: false)
如果设置为true,那么boolean型字段生成的getter将使用get前缀而不是默认的is前缀
5.@ToString
生成一个toString方法,log debug神器
默认的toString格式为:ClassName(fieldName= fieleValue ,fieldName1=fieleValue)
-
import lombok.ToString;
-
-
@ToString(exclude=
"id")
-
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.getName();
-
}
-
-
@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.getName();
-
}
-
-
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) +
")";
-
}
-
}
扩展配置:
lombok.toString.includeFieldNames
= [true
| false
] (default: true)
通常,lombok以fieldName=fieldValue的形式为每个字段生成一个toString响应的片段。如果设置为false,lombok将省略字段的名称,可以在该注解上配置属性includeFieldNames来标示包含的字段,这样可以覆盖默认配置。
lombok.toString.doNotUseGetters
= [
true
|
false
] (default: false)
如果设置为true,lombok将直接访问字段,而不是在生成tostring方法时使用getter(如果可用)。可以在该注解上配置属性doNotUseGetters来标示不使用getter的字段,这样可以覆盖默认配置。
6.@EqualsAndHashCode
给类增加equals和hashCode方法
-
import lombok.EqualsAndHashCode;
-
-
@EqualsAndHashCode(exclude={
"id",
"shape"})
-
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;
-
}
-
-
@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;
-
}
-
}
-
}
扩展配置:
lombok.config增加:
lombok.equalsAndHashCode.doNotUseGetters
= [true
| false
]
(default: false)如果设置为true,lombok将直接访问字段,而不是在生成equals和hashcode方法时使用getter(如果可用)。
可以在该注解上配置属性donotusegetter来标示不使用getter的字段,这样可以覆盖默认配置。
lombok.equalsAndHashCode.callSuper
= [call
| skip
| warn
]
(default: warn)如果设置为call,lombok将生成对hashCode的超类实现的调用。如果设置为skip,则不会生成这样的调用。默认行为warn类似于skip,并带有附加警告。
7.@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor
给类增加无参构造器 指定参数的构造器 包含所有参数的构造器
-
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() {
-
}
-
}
-
}
扩展配置:
lombok.anyConstructor.suppressConstructorProperties
= [true
| false
]
(default: false
)如果将其设置为true,那么lombok将跳过添加一个@java.bean.ConstructorProperties生成的构造器。这在android和GWT开发中很有用,因为这些注释通常不可用。
8.@Data
包含以下注解的集合
@ToString,@EqualsAndHashCode,所有字段的 @Getter 所有非final字段的@Setter ,@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;
-
}
-
}
-
}
9.@Value
@value是@data的不可变对象 (不可变对象的用处和创建:https://my.oschina.net/jasonultimate/blog/166810)
所有字段都是私有的,默认情况下是final的,并且不会生成setter。默认情况下,类本身也是final的,因为不可变性不能强制转化为子类。与@data一样,有用toString()、equals()和hashCode()方法也是生成的,每个字段都有一个getter方法,并且一个覆盖每个参数的构造器也会生成。
10.@Builder
建筑者模式
是现在比较推崇的一种构建值对象的方式。
-
import lombok.Builder;
-
import lombok.Singular;
-
import java.util.Set;
-
-
@Builder
-
public
class BuilderExample {
-
private String name;
-
private
int age;
-
@Singular
private Set<String> occupations;
-
}
翻译后
-
import java.util.Set;
-
-
public
class BuilderExample {
-
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;
-
}
-
-
public static BuilderExampleBuilder builder() {
-
return
new BuilderExampleBuilder();
-
}
-
-
public
static
class BuilderExampleBuilder {
-
private String name;
-
private
int age;
-
private java.util.ArrayList<String> occupations;
-
-
BuilderExampleBuilder() {
-
}
-
-
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.
-
// go to https://projectlombok.org/features/Singular-snippet.html to see it.
-
Set<String> occupations = ...;
-
return
new BuilderExample(name, age, occupations);
-
}
-
-
@java.lang.
Override
-
public String
toString
() {
-
return
"BuilderExample.BuilderExampleBuilder(name = " +
this.name +
", age = " +
this.age +
", occupations = " +
this.occupations +
")";
-
}
-
}
-
}
11.@SneakyThrows
把checked异常转化为unchecked异常,好处是不用再往上层方法抛出了,美其名曰暗埋异常
-
import lombok.SneakyThrows;
-
-
public
class SneakyThrowsExample implements Runnable {
-
@SneakyThrows(UnsupportedEncodingException.class)
-
public String utf8ToString(byte[] bytes) {
-
return
new String(bytes,
"UTF-8");
-
}
-
-
@SneakyThrows
-
public void run() {
-
throw
new Throwable();
-
}
-
}
翻译后:
-
import lombok.Lombok;
-
-
public
class SneakyThrowsExample implements Runnable {
-
public String utf8ToString(byte[] bytes) {
-
try {
-
return
new String(bytes,
"UTF-8");
-
}
catch (UnsupportedEncodingException e) {
-
throw Lombok.sneakyThrow(e);
-
}
-
}
-
-
public void run() {
-
try {
-
throw
new Throwable();
-
}
catch (Throwable t) {
-
throw Lombok.sneakyThrow(t);
-
}
-
}
-
}
12.@Synchronized
类似于Synchronized 关键字 但是可以隐藏同步锁
-
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");
-
}
-
}
-
}
xianzjdk推荐使用Lock了,这个仅供参考
13.@Getter(lazy=true)
如果getter方法计算值需要大量CPU,或者值占用大量内存,第一次调用这个getter,它将一次计算一个值,然后从那时开始缓存它
-
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;
-
}
-
}
14.@Log
可以生成各种log对象,方便多了
-
import lombok.extern.java.Log;
-
import lombok.extern.slf4j.Slf4j;
-
-
@Log
-
public
class LogExample {
-
-
public static void main(String... args) {
-
log.error(
"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.error(
"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");
-
}
-
}
所有支持的log类型:
@CommonsLog
Createsprivate static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
@JBossLog
Createsprivate static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
@Log
Createsprivate static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
@Log4j
Createsprivate static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
@Log4j2
Createsprivate static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
@Slf4j
Creates private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
@XSlf4j
Createsprivate static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
扩展配置:
lombok.log.fieldName
= an identifier (default: log
).生成log字段的名称 默认为log
lombok.log.fieldIsStatic
= [true
| false
]
(default: true)生成log是否是static的 默认为static
官方文档说明:https://projectlombok.org/features/all
Lombok原理
![](https://i-blog.csdnimg.cn/blog_migrate/8e42594d99202ef4535e1fa5fe59134c.gif)
1)javac对源代码进行分析,生成一棵抽象语法树(AST)
2)运行过程中调用实现了"JSR 269 API"的lombok程序
3)此时lombok就对第一步骤得到的AST进行处理,找到@Data注解所在类对应的语法树(AST),然后修改该语法树(AST),增加getter和setter方法定义的相应树节点
4)javac使用修改后的抽象语法树(AST)生成字节码文件,即给class增加新的节点(代码块)
ide中使用Lombok的注意事项
1.项目中要使用lombok 不仅ide要支持(否则一堆错误),项目中也要引入jar包
2.如果配置lombok.config文件,修改文件的属性值后,并不会自动重新编译class文件,ide编辑器也不会自动更新,所有每次修改配置文件后最后关闭java文件窗口重新打开,并且clean下项目