大家好,欢迎来到IT知识分享网。
一. 为什么要用@Accessors?
通常,在创建对象的时候,我们使用构造函数为成员变量赋值。一个对象的初始化,参数有时候不固定,所以就有了参数不同的构造函数。但是,如果一个类的成员变量很多,那么就有可能产生很多的构造函数。当然,你可以使用无参的构造函数先创建一个对象,再去调用setter方法为需要初始化的变量赋值。这样做的弊端很明显,就是一行行的setter方法费时费力。不然,也不会有不同的构造函数。但是,即使有了很多不同的构造函数,对于创建一个复杂的对象(拥有很多成员变量)也很棘手。因为在new的过程中,当我们传入构造函数的参数很多,会出现这样一种情况——不知道这个参数具体是干什么的。这时候构造函数,似乎不如setter方法那样清晰明了,因为setter方法名可以帮助我们了解这个参数具体的作用。
那么有没有办法,让我们在创建对象的过程中,既能拥有多个构造函数的参数不确定的特点,同时又能够像setter方法那样知道每个参数具体的作用呢?其实这就是我们常说的建造者模式,在《Lombok之@Builder使用》中,我们知道了@Builder可以实现这样的功能。不过,它也有点缺陷——无法在创建对象后继续使用链式赋值。幸运的是,Lombok出了一个@Accessors注解,完美地解决了这个问题,它可以让你随时随地使用链式赋值。
二. @Accessors如何使用?
在@Accessors的官方文档中,对于@Accessors的总结是——A more fluent API for getters and setters.意为:面向getter和setter的更流畅的API。所以,@Accessors是配合@Getter/@Setter注解一起使用的。代码如下:
@Getter
@Setter
@Accessors(fluent = true, chain = true)
public class Student {
private String name;
private Integer age;
}
反编译后的代码如下:
public class Student {
private String name;
private Integer age;
public Student() {
}
public String name() {
return this.name;
}
public Integer age() {
return this.age;
}
public Student name(String name) {
this.name = name;
return this;
}
public Student age(Integer age) {
this.age = age;
return this;
}
}
可以看到,所有的getter和setter方法都使用了变量名的作为方法名。setter方法的返回值全是Student类型。代码演示:
三. @Accessors源码
package lombok.experimental;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** * A container for settings for the generation of getters and setters. * <p> * Complete documentation is found at <a href="https://projectlombok.org/features/experimental/Accessors">the project lombok features page for @Accessors</a>. * <p> * Using this annotation does nothing by itself; an annotation that makes lombok generate getters and setters, * such as {@link lombok.Setter} or {@link lombok.Data} is also required. */
@Target({
ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Accessors {
/** * If true, accessors will be named after the field and not include a {@code get} or {@code set} * prefix. If true and {@code chain} is omitted, {@code chain} defaults to {@code true}. * <strong>default: false</strong> * * @return Whether or not to make fluent methods (named {@code fieldName()}, not for example {@code setFieldName}). */
boolean fluent() default false;
/** * If true, setters return {@code this} instead of {@code void}. * <strong>default: false</strong>, unless {@code fluent=true}, then <strong>default: true</strong> * * @return Whether or not setters should return themselves (chaining) or {@code void} (no chaining). */
boolean chain() default false;
/** * If present, only fields with any of the stated prefixes are given the getter/setter treatment. * Note that a prefix only counts if the next character is NOT a lowercase character or the last * letter of the prefix is not a letter (for instance an underscore). If multiple fields * all turn into the same name when the prefix is stripped, an error will be generated. * * @return If you are in the habit of prefixing your fields (for example, you name them {@code fFieldName}, specify such prefixes here). */
String[] prefix() default {
};
}
- 元注解:@Target({ElementType.TYPE, ElementType.FIELD}),@Retention(RetentionPolicy.SOURCE)
- 注解属性:fluent注解默认值为false,则保留getter和setter方法前面的get和set前缀。如果为true,则不保留前缀,直接使用变量名作为方法名,也就构成了方法的重载。
值得注意的是,当fluent为true时,chain注解属性的值就自动设置成了true。chain的默认值是false,意味不启用链式赋值,也就是setter方法返回体为void。
prefix注解属性处理变量名前缀的,只有拥有前缀的变量才会生成getter/setter方法,而且它的匹配原则是——匹配到的变量去掉前缀后第一个字母不能是小写。通俗地说就是,运用驼峰命名规则去匹配。
四. 特别说明
本文已经收录在Lombok注解系列文章总览中,并继承上文中所提的特别说明。
源码地址:gitee
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/24194.html