文章16 | 阅读 7100 | 点赞0
在开发过程中,不可变类其实经常用到。不可变类是指创建该类的实例后,该实例的实例变量是不可改变的。Jav提供的8个包装类和java.lang.String类都是不可变类。对于不可变类的理解可以先参考这篇博客《java中的不可变类》。现在,我们知道不可变类和其它普通类是不同的,它有以下几点具体要求:(注:不可变类的详细策略参考官网)
在开发过程中,我们编写不可变类时需要满足以上条件,以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的使用十分简单,只需在类上加上该注解即可。我们将上面的Student使用@Value改造一下:
@Value
public class Student {
String name;
Integer age;
}
就一个注释?对,就一个注释。编译后,查看反编译文件和上面是相同的。(上面的代码就是反编译出来的,我可没那么多时间自己实现不可变类:D)
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 @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
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/cauchy6317/article/details/102646009
内容来源于网络,如有侵权,请联系作者删除!