Lombok
Lombok 笔记
https://projectlombok.org
Lombok:让JAVA代码更优雅
http://blog.didispace.com/java-lombok-1/
常用注解
@Data
注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法
@Data 是 @Getter、 @Setter、 @ToString、 @EqualsAndHashCode 和 @RequiredArgsConstructor 的快捷方式。
Generating equals/hashCode implementation but without a call to superclass
@Data 报 warning
Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add ‘(callSuper=false)’ to your type.
原因:
Lombok @Data 注解在子类上时 IDEA 会给出这个提示,原因是生成的 equals/hashcode 方法没有涵盖父类的字段
解决:
1、加上 @EqualsAndHashCode(callSuper = true)
2、在 src/main/java 文件夹下加 lombok 统一配置文件
config.stopBubbling=true
lombok.equalsAndHashCode.callSuper=call
lombok.addLombokGeneratedAnnotation=true
@NoArgsConstructor
注解在类上;为类提供一个无参的构造方法
@AllArgsConstructor
注解在类上;为类提供一个全参的构造方法
@RequiredArgsConstructor
注解在类上;为类提供一个必要参数的构造方法
什么是必要参数?
1、未初始化的 final 修饰的成员变量
2、@NonNull 修饰的成员变量
另外,如果所有的属性都没有final修饰的话,使用 @RequiredArgsConstructor 会生成一个无参的构造器。
构造器注入与@RequiredArgsConstructor结合
构造器结合 lombok 的 @RequiredArgsConstructor
一起使用,会让代码更加简单
@Component
@RequiredArgsConstructor
public class ThankingService {
private final Translator translator;
public String produce() {
return translator.translate("thank you");
}
}
等价于
@Component
public class ThankingService {
private final Translator translator;
public String thank() {
return translator.translate("thank you");
}
/* Generated by Lombok */
public ThankingService(Translator translator) {
this.translator = translator;
}
}
由于只有一个构造方法,Spring 可以唯一选择这个构造方法来初始化 ThankingService 并自动注入 Translator 实例。
Constructor Injection in Spring with Lombok
https://www.baeldung.com/spring-injection-lombok
@Buidler 建造者模式
实现建造者模式
当你使用 @Builder 注解 User 类时, Lombok 会执行以下操作:
加一个私有构造函数到 User
创建一个静态的 UserBuilder 类
在 UserBuilder 中为 User 中的每个成员创建一个 setter 风格方法
在 UserBuilder 中添加创建 User 的新实例的建造方法
@SuperBuilder 继承父类属性的构造器
@Buidler 只能针对当前类的 field 生成构造器,无法继承父类的 field, 即使给父类也添加 @Builder 注解也依然不能通过链式调用给父类 field 赋值。
Lombok 在 v1.18.2 版本中针对这个问题增加了 @SuperBuilder 注解,子类和父类中都添加 @SuperBuilder 注解,子类 builder 即可继承父类 builder。
@Builder.Default builder默认值
如果不加 @Builder.Default
的话,通过 builder 构建的 PageRequest 的 pageRequest 字段是没有默认值的,必须加上 @Builder.Default
才有
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class PageRequest {
@Builder.Default
private ApiPageRequest pageRequest = ApiPageRequest.builder().pageNumber(1).pageSize(20).build();
}
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "user", uniqueConstraints = {@UniqueConstraint(name = "uk_name", columnNames = {"name"})})
public class UserDO {
private String name;
/**
* 状态 enabled/disabled
*/
@Enumerated(EnumType.STRING)
@ColumnDefault("'ENABLED'")
@Builder.Default
private StatusEnum status = StatusEnum.ENABLED;
}
@SLF4J
https://projectlombok.org/features/log
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
https://projectlombok.org/features/experimental/SuperBuilder
@UtilityClass 标识工具类
工具类中所有方法都必须是 static 的,不能有任何实例
https://projectlombok.org/features/experimental/UtilityClass
@EqualsAndHashCode
https://projectlombok.org/features/EqualsAndHashCode
@EqualsAndHashCode
用于自动生成 equals(Object other)
和 hashCode()
方法。
默认会使用全部 非 static、非 transient 的字段,但也可以手动指定。
可以在字段上注解 @EqualsAndHashCode.Include
来指定包含,或者注解 @EqualsAndHashCode.Exclude
来指定排除。
还可以通过在指定字段上注解 @EqualsAndHashCode.Include
并使用 @EqualsAndHashCode(onlyExplicitlyIncluded = true)
来完全手动指定包含的字段。
对于有父类的情况,加 callSuper=true
属性会使得生成的 equals(Object other)
和 hashCode()
方法内部调用父类的 equals(Object other)
和 hashCode()
方法。
@EqualsAndHashCode(of = {“code”}, callSuper = true)
@ToString.Exclude
注解需要从 toString 方法排除的字段
@SneakyThrows 优雅抛出受检异常
@SneakyThrows 注解在会抛出受检异常的方法上,相当于直接将受检异常抛出。但这么写不用显式 throw,也不用 try catch,非常简洁。
@SneakyThrows
public void sneakyThrows() {
throw new Exception("exp");
}
反 lombok 后是:
public void sneakyThrows() {
try {
throw new Exception("exp");
} catch (Throwable t) {
throw Lombok.sneakyThrow(t);
}
}
实际上等于
public void sneakyThrows() throw Exception {
throw new Exception("exp");
}
内部实现是利用泛型将 Throwable 强转为 RuntimeException 抛出以达到欺骗 java 编译器的目的,编译器看到是 RuntimeException 就不做检查,但实际运行中 泛型擦除 后还是抛出原异常,异常不会被吞掉。
package lombok;
public class Lombok {
public static RuntimeException sneakyThrow(Throwable t) {
if (t == null) throw new NullPointerException("t");
return Lombok.<RuntimeException>sneakyThrow0(t);
}
private static <T extends Throwable> T sneakyThrow0(Throwable t) throws T {
throw (T)t;
}
}
lombok.config
可通过 lombok.config 配置文件配置 lombok 属性,可以放在任何目录,作用于该目录和其子目录
config.stopBubbling=true 指明lombok的根目录为当前配置文件所在目录
问题
编译错误:无法将类 A 中的构造器 A应用到给定类型
java重要特性:子类除了拥有自己的特性外还拥有父类的特性。
因此在初始化子类的时候,父类也要被初始化。
比如定义了类
class A {
//这样系统不会为类A自动加上无参的构造函数
public A(int x){}
}
class B extends A {
//这样系统会自动为B加上无参的构造函数,而且在这个构造函数里有一句话super();
}
所以编译时,A编译通过,但是编译B时会提示无法将A中的构造器应用到给定的类型,因为 super()
找不到A中的无参构造器
解决方法:
一、在A中加入无参的构造方法
二、在B中的所有构造方法的第一句话写上super(int);
无法将构造器应用到给定的类型
https://blog.csdn.net/songxueyu/article/details/14447201
IDEA安装lobbok插件
定位到 File > Settings > Plugins
点击 Browse repositories…
搜索 Lombok Plugin
点击 Install plugin
重启 IDEA
上一篇 Prometheus监控
页面信息
location:
protocol
: host
: hostname
: origin
: pathname
: href
: document:
referrer
: navigator:
platform
: userAgent
: