文章9 | 阅读 3683 | 点赞0
@toString
任何类定义都可以用@ToString
注释,让lombok
生成toString()
方法的实现。 默认情况下,它会按顺序打印类名和每个字段,并以逗号分隔,如下所示:
@Getter
@Setter
@ToString
public class User {
private String username;
private String password;
private boolean isAdult;
}
// 编译后:
public class User {
private String username;
private String password;
private boolean isAdult;
// 其他省略
public String toString() {
return "User(username=" + this.getUsername() +
", password=" + this.getPassword() +
", isAdult=" + this.isAdult() + ")";
}
}
在编译后地结果中可以看到,lombok
默认使用的是getter
方法进行设值,如this.getUsername()
,但是我们实际并不需要通过getter
的方式进行设置,lombok
也知道我们有这样的需求,为我们提供了注解配置项,下面我们就来继续看看如何进行更个性化的配置@toString
。
@toString
深度研究一个东西,肯定少不了源码的分析,当然@toString
的代码并不难,放一百个心,如下所示:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ToString {
// 输出是否带字段名称
boolean includeFieldNames() default true;
// 排除字段,以 String[] 格式设置
String[] exclude() default {};
// 指定输出哪些字段,不过将来会被标注@deprecated,使用 @ToString.Include 替代
String[] of() default {};
// 是否调用父类的 toString() 方法
boolean callSuper() default false;
// 不使用 getter 方法获取字段值
boolean doNotUseGetters() default false;
// 是否只输出被 @ToString.Include 备注的属性,默认情况输出所有非静态字段
boolean onlyExplicitlyIncluded() default false;
// 标注不被输出的字段
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Exclude {}
// 标注被输出的字段 @ToString.Include
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Include {
// 输出字段的顺序,值越高越先被输出
int rank() default 0;
// 默认为带注释的成员的字段/方法名称。可以使用此方式使用新的名称
String name() default "";
}
}
下面我们快速写点demo测试一遍,以下的代码实例只针对toString
部分
@ToString(
includeFieldNames = false
)
@Getter @Setter
public class User {
private String username,password;
private boolean isAdult;
}
// 编译后:
public String toString() {
return "User(" + this.getUsername() + ", " + this.getPassword() + ", " + this.isAdult() + ")";
}
@ToString(
doNotUseGetters = true
)
@Getter @Setter
public class User {
private String username,password;
private boolean isAdult;
}
// 编译后:
public String toString() {
return "User(username=" + this.username + ", password=" + this.password + ", isAdult=" + this.isAdult + ")";
}
@ToString(
doNotUseGetters = true,
exclude = {"password","isAdult"}
)
@Getter @Setter
public class User {
private String username,password;
private boolean isAdult;
}
// 编译后:
public String toString() {
return "User(username=" + this.username + ")";
}
@ToString(
doNotUseGetters = true,
onlyExplicitlyIncluded = true
)
@Getter @Setter
public class User {
@ToString.Include // 指定字段
private String username,password;
private boolean isAdult;
}
// 编译后:
public String toString() {
return "User(username=" + this.username +
", password=" + this.password + ")";
}
@ToString(
doNotUseGetters = true,
onlyExplicitlyIncluded = true
)
@Getter @Setter
public class User {
@ToString.Include(rank = 1)
private String username;
@ToString.Include(rank = 2,name = "pwd")
private String password;
private boolean isAdult;
}
// 编译后:
public String toString() {
return "User(pwd=" + this.password + ", username=" + this.username + ")";
}
在上面,我故意设置password
别名为pwd
,并设置输出rank
值大于username
的rank
的值。
@toString
全局配置# 是否指定只有标注了 @ToString.Include 注解的属性字段才被输出
lombok.toString.includeFieldNames = [true | false] (default: true)
# 是否指定使用 getter 方法获取字段属性值,默认是使用 getter
lombok.toString.doNotUseGetters = [true | false] (default: false)
# 是否调用父类 toString 方法。
# call:调用父类toString方法
# skip:不调用父类toString方法(建议使用默认值)
# warn:不调用父类toString方法,但是会有提示
lombok.toString.callSuper = [call | skip | warn] (default: skip)
# 如果启用,会将标注了@toString 的注解,提示error或warning
lombok.toString.flagUsage = [warning | error] (default: not set)
如果有疑问请留言!!!
Equality made easy: Generates hashCode
and equals
implementations from the fields of your object.
@EqualsAndHashCode
任何类定义都可以使用@EqualsAndHashCode
进行注释,lombok
会生成equals(Object other)
和hashCode()
方法的实现。
默认情况下,它将使用所有non-static
,non-transient
字段,当然你可以通过使用@EqualsAndHashCode.Include
标记类成员来修改使用哪些字段,或者使用@ EqualsAndHashCode.Exclude
标记类成员不使用哪些字段。
你可以通过使用@EqualsAndHashCode.Include
并使用@EqualsAndHashCode(onlyExplicitlyIncluded = true)
标记它们来准确指定希望使用的字段或方法。
@ToString
@Getter @Setter
@EqualsAndHashCode
public class User {
private String username,password;
private boolean isAdult;
}
// 编译后
public class User {
// 其他省略
public boolean equals(Object o) { // 具体实现省略(代码量太多) }
protected boolean canEqual(Object other) { return other instanceof User; }
public int hashCode() {
int PRIME = true;
int result = 1;
Object $username = this.getUsername();
int result = result * 59 + ($username == null ? 43 : $username.hashCode());
Object $password = this.getPassword();
result = result * 59 + ($password == null ? 43 : $password.hashCode());
result = result * 59 + (this.isAdult() ? 79 : 97);
return result;
}
}
@EqualsAndHashCode
为了搞清楚具体配置,我觉得还是有必要看看@EqualsAndHashCode
注解的源码内容的:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface EqualsAndHashCode {
// 排除指定字段
String[] exclude() default {};
// 包含指定字段,将来会不再使用,使用 @EqualsAndHashCode.Include 代替
String[] of() default {};
// 是否在计算之前调用父类的实现
boolean callSuper() default false;
// 是否使用 getter
boolean doNotUseGetters() default false;
// 在生成的 equals 和 hashCode 的入参添加注解。e.g. @NonNull
// up to JDK7: @EqualsAndHashCode(onParam=@__({@AnnotationsGoHere}))
// from JDK8: @EqualsAndHashCode(onParam_={@AnnotationsGohere})
AnyAnnotation[] onParam() default {};
// 是否只使用 @EqualsAndHashCode.Include 标注的字段
boolean onlyExplicitlyIncluded() default false;
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
@interface AnyAnnotation {}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Exclude {}
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Include {
String replaces() default "";
}
}
下面我们快速写点demo测试一下在指定字段上添加注解这个配置,其余的配置皆可以参考@toString
中的示例配置,以下的代码实例只针对EqualsAndHashCode
部分
equals()
和hashCode()
的入参加注解@ToString
@Getter @Setter
@EqualsAndHashCode(
onParam_= {@NotNull}
)
public class User {
private String username,password;
private boolean isAdult;
}
// 编译后:
public class User {
// 其他省略
public boolean equals(@NotNull Object o) { }
protected boolean canEqual(@NotNull Object other) {
return other instanceof User;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $username = this.getUsername();
int result = result * 59 + ($username == null ? 43 : $username.hashCode());
Object $password = this.getPassword();
result = result * 59 + ($password == null ? 43 : $password.hashCode());
result = result * 59 + (this.isAdult() ? 79 : 97);
return result;
}
@EqualsAndHashCode
全局配置# 是否指定使用 getter 方法获取字段属性值,默认是使用 getter
lombok.equalsAndHashCode.doNotUseGetters = [true | false] (default: false)
# 是否在计算之前调用父类的实现
lombok.equalsAndHashCode.callSuper = [call | skip | warn] (default: warn)
# 是否禁用 @EqualsAndHashCode
lombok.equalsAndHashCode.flagUsage = [warning | error] (default: not set)
如果有疑问请留言!!!
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_41540822/article/details/86606467
内容来源于网络,如有侵权,请联系作者删除!