Lombok之@Value使用

一. 为什么要用@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

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值