Lombok之@Value使用

x33g5p2x  于2021-12-25 转载在 其他  
字(3.2k)|赞(0)|评价(0)|浏览(537)

一. 为什么要用@Value?

在开发过程中,不可变类其实经常用到。不可变类是指创建该类的实例后,该实例的实例变量是不可改变的。Jav提供的8个包装类和java.lang.String类都是不可变类。对于不可变类的理解可以先参考这篇博客《java中的不可变类》。现在,我们知道不可变类和其它普通类是不同的,它有以下几点具体要求:(注:不可变类的详细策略参考官网

  • 使用private和final修饰符来修饰该类的成员变量;
  • 提供带参数的构造器,根据传入的参数来初始化类里的成员变量;
  • 仅为该类的成员变量提供getter方法,不要提供setter方法,因为普通方法无法修改final修饰的成员变量;
  • 不允许子类覆盖方法。最简单的方法是将该类声明为final。一种更复杂的方法是使用private工厂方法来构造构造器和构造实例。
  • 如果有必要,重写Object类的hascode()和equals()方法。equals方法根据关键成员变量来作为两个对象是否相等的标准,除此之外,还应该保证两个用equals方法判断为相等的对象的hashCode()也相等。

在开发过程中,我们编写不可变类时需要满足以上条件,以Student类为例。

public final class Student {
    private final String name;
    private final Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return this.name;
    }

    public Integer getAge() {
        return this.age;
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Student)) {
            return false;
        } else {
            Student other = (Student)o;
            Object this$name = this.getName();
            Object other$name = other.getName();
            if (this$name == null) {
                if (other$name != null) {
                    return false;
                }
            } else if (!this$name.equals(other$name)) {
                return false;
            }

            Object this$age = this.getAge();
            Object other$age = other.getAge();
            if (this$age == null) {
                if (other$age != null) {
                    return false;
                }
            } else if (!this$age.equals(other$age)) {
                return false;
            }

            return true;
        }
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $name = this.getName();
        int result = result * 59 + ($name == null ? 43 : $name.hashCode());
        Object $age = this.getAge();
        result = result * 59 + ($age == null ? 43 : $age.hashCode());
        return result;
    }

    public String toString() {
        return "Student(name=" + this.getName() + ", age=" + this.getAge() + ")";
    }

可以看到,上面Student类就是一个典型的不可变类。这样的不可变类,用代码实现起来并不复杂,只是篇幅过长,而且不可变类的要求是相同的。所以,Lombok给出了一个注解@Value来表明一个类是不可变类。

二. @Value如何使用?

@Value的使用十分简单,只需在类上加上该注解即可。我们将上面的Student使用@Value改造一下:

@Value
public class Student {

    String name;

    Integer age;
}

就一个注释?对,就一个注释。编译后,查看反编译文件和上面是相同的。(上面的代码就是反编译出来的,我可没那么多时间自己实现不可变类:D)

三. @Value源码

package lombok;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/** * Generates a lot of code which fits with a class that is a representation of an immutable entity. * <p> * Equivalent to {@code @Getter @FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE) @AllArgsConstructor @ToString @EqualsAndHashCode}. * <p> * Complete documentation is found at <a href="https://projectlombok.org/features/Value">the project lombok features page for &#64;Value</a>. * * @see lombok.Getter * @see lombok.experimental.FieldDefaults * @see lombok.AllArgsConstructor * @see lombok.ToString * @see lombok.EqualsAndHashCode * @see lombok.Data */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Value {
	/** * If you specify a static constructor name, then the generated constructor will be private, and * instead a static factory method is created that other classes can use to create instances. * We suggest the name: "of", like so: * * <pre> * public @Value(staticConstructor = "of") class Point { final int x, y; } * </pre> * * Default: No static constructor, instead the normal constructor is public. * * @return Name of static 'constructor' method to generate (blank = generate a normal constructor). */
	String staticConstructor() default "";
}

只有一个staticConstructor注解属性,其用法和《Lombok之@Data使用》中的staticConstructor相同。

四. 特别说明

本文已经收录在Lombok注解系列文章总览中,并继承上文中所提的特别说明。
源码地址:gitee

相关文章