Lombok使用5—@Data & @Value

image
All together now: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, @Setter on all non-final fields, and @RequiredArgsConstructor!

1. @Data

1.1 @Data 实战使用

@Data是一个方便的快捷方式注释,它将@ToString,@EqualsAndHashCode,@Getter/@Setter和@RequiredArgsConstructor的特性捆绑在一起。

换句话说,@Data生成通常与简单POJOs和beans配合使用,它会进行以下操作:

  • 生成所有字段的getter,所有非final字段的setter,
  • 实现相应类字段的toString,equals,和hashCode,
  • 构造方法将初始化所有没有初始化值的final字段,和所有使用@NonNull标记却没有初始化值的非final字段,从而确保字段永远不为空。
    估计你听着会有点绕,先来一个小菜常常鲜!
@Data
public class User {
    private final Integer id;
    private final String zipCode = "215500";
    @NonNull
    private String username;
    private String password;
}
// 编译后:
public class User {
    private final Integer id;
    private final String zipCode = "215500";
    @NonNull
    private String username;
    private String password;

    // 生成带有未初始化的 final 字段,以及标有 @NonNull 的字段
    public User(Integer id, @NonNull String username) {
        if (username == null) {
            throw new NullPointerException("username is marked @NonNull but is null");
        } else {
            this.id = id;
            this.username = username;
        }
    }

    public Integer getId() { return this.id; }
    public String getZipCode() {
        this.getClass();
        return "215500";
    }
    @NonNull
    public String getUsername() { return this.username; }
    public String getPassword() { return this.password; }

    // 只生成非 final 的字段的 setter 方法
    public void setUsername(@NonNull String username) {
        if (username == null) {
            throw new NullPointerException("username is marked @NonNull but is null");
        } else {
            this.username = username;
        }
    }
    public void setPassword(String password) { this.password = password; }
	// 省略 toString,canEquals,equals,hashCode 相关代码
}

看到编译后地代码,可以明确地看到为我们生成了所有参数的getter&setter,constructor,toString,hashCode。你可能会说@Data一个注解就能满足实际工作需求,莫急,听我慢慢道来……

现在我们再来解释一下上面说的几条生成规则:

  • 可以看到所有的字段的getter都被生成,非final的setter方法被生成。(这主要是因为,在构造方法中对final字段进行了初始化,要知道final字段一旦被初始化后,将不能再被修改)
  • 实现相应类字段的toString,equals,和hashCode,这没得说。
  • 再看最后一个,再生成构造器时,会生成带有这样两种参数的构造器:
    1.实体类有未被初始化的 final字段
    2.实体类中标有@NonNull注解的字段

1.2 @Data 注解配置详解
当我看到@Data的注解源码时,心里是抵触的,不愿接受的,这么好用的功能,为啥就不能丰富一下呢?

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
	// 使用静态构造方法,私有实体构造器,通过 staticConstructor 配置静态构造方法的名称
	String staticConstructor() default "";
}

1.3 @Data 使用注意事项

  • getter和setter默认是public的,如果需要改变修饰符请使用@Setter和@Getter;
  • transient类型的变量不会被hashcode和equals使用,静态变量也会被跳过;
  • 虽然@Data注解非常有用,但是它没有与其他注解相同的控制粒度。@Data提供了一个可以生成静态工厂的单一参数,将staticConstructor参数设置为所需要的名称,Lombok自动生成的构造函数设置为私有,并提供公开的给定名称的静态工厂方法@Data(staticConstructor=”of”)
  • 同时使用@Data和@AllArgsConstructor后 ,默认的无参构造函数失效,如果需要它,要重新设置 @NoArgsConstructor

1.4 @Data 全局配置

也是抵触的,啥配置也没提供!

lombok.data.flagUsage = [warning | error] (default: not set)

2. @Value

Immutable classes made very easy.
@Value promoted to the main lombok package since lombok v0.12.0.

2.1 @Value 实战使用

@Value注解用于修饰类,相当于是@Data的不可变形式,因为字段都被修饰为private和final,默认的情况下不会生成settter。还有一点更狠的,默认类本身也是final的,不能被继承。

官方给出:实际上@Value相当于:final @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Getter

先不说那么多,小试牛刀一下:

@Value
public class User {
    private final Integer id;
    private final String zipCode = "215500";
    @NonNull
    private String username;
    private String password;
}
// 编译后:
public final class User {
    private final Integer id;
    private final String zipCode = "215500";
    @NonNull
    private final String username;
    private final String password;

    public User(Integer id, @NonNull String username, String password) {
        if (username == null) {
            throw new NullPointerException("username is marked @NonNull but is null");
        } else {
            this.id = id;
            this.username = username;
            this.password = password;
        }
    }

    public Integer getId() { return this.id; }
    public String getZipCode() {
        this.getClass();
        return "215500";
    }
    @NonNull
    public String getUsername() { return this.username; }
    public String getPassword() { return this.password; }

	// 省略 toString,canEquals,equals,hashCode 相关代码
}

在编译后地代码中,没有发现setter方法,会生成一个带有所有的非final字段和未初始化的final字段的构造器。

生成相应的toString,canEquals,equals,hashCode方法

2.2 @Value 注解详解

多么痛的领悟!感觉@Data和@Value都是潜力股

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Value {
	// 使用静态构造方法,私有实体构造器,通过 staticConstructor 配置静态构造方法的名称
	String staticConstructor() default "";
}

2.3 @Value 全局配置

这个全局配置没啥好说的……

lombok.value.flagUsage = [warning | error] (default: not set)

3 参考文档

https://www.projectlombok.org/

更新时间:2020-09-11 09:38:49

本文由 清水河恶霸 创作,如果您觉得本文不错,请随意赞赏
采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
原文链接:http://ql.magic-seven.top/2020/09/11/lombok使用5datavalue.html
最后更新:2020-09-11 09:38:49

评论

Your browser is out of date!

Update your browser to view this website correctly. Update my browser now

×