Java类的属性get与set方法及lombok库的使用
一、前言
在Java面向对象的开发中,通过Class定义类,类中包括字段(属性)、方法、构造函数等。在由类创建具体实例时,通过类中属性的get(设置器)和set(访问器)设置或者访问类中的属性。使用过程中,我们都清楚如何使用属性,但是1、属性的访问修饰符为什么设置成private;2、为什么要使用get和set方法;3、lombok库的注解的使用和区别。通过上述问题的详细介绍来学习关于类属性的使用。
二、类的get与set方法
在面向对象的特性中有继承、封装、多态性,封装是保护类创建对象的数据和行为,将其隐藏在类的内部,并提供公共的方法来访问成员变量和成员函数,从而确保数据的安全访问,防止数据被任意修改。在Java中通过修饰符(private、public、protected)来实现封装,类的属性属于成员变量,类外部的其它对象访问类内属性必须提供一种安全的访问方式,所以通过创建set或者get方法来访问属性。
/** * */ public class Student { /** * id */ private Long id; public Long getId(){ return id; } public void setId(long id) { this.id = id; } /** * 姓名 */ private String name; public String getName() { return name; } public void setName(String name){ this.name = name; } /** * 年龄 */ private Integer age; public Integer getAge(){ return age; } private void setAge(){ this.age = age; } /** * 出生年月 */ private LocalDate birthday; public LocalDate getBirthday() { return birthday; } public void setBirthday(LocalDate birthday) { this.birthday = birthday; } /** * 地址 */ private Address address; public Address getAddress() { return address; } public void setAddress(Address address){ this.address = address; } }
上述定义Student类,类中定义值类型或者引用类型的属性(id、name、age、address)并且设置访问修饰符private,在没有设置相应的访问器时,外部创建Student实例无法访问其属性,达到内部细节的隐藏和封装性,要访问该属性如上设置每一个属性的get和set方法。
在使用get和set方法,我们通过①不设置get方法或者不设置set方法或者定义其访问修饰符来限制权限;②在set方法中写入相关验证规则、条件等进行判断,阻止非法的值设置;③在类中一些属性是其它属性的附属属性,则在该属性中的get方法中通过其它属性计算来获取,关闭设置方法。
package com.example.demo; import com.sun.deploy.util.StringUtils; import java.time.LocalDate; import java.time.Period; /** * */ public class Student { /** * id */ private Long id; public Long getId(){ return id; } public void setId(long id) { this.id = id; } /** * 姓名 */ private String name; public String getName() { return name; } public void setName(String name) throws Exception { if(name.isEmpty()){ throw new Exception("姓名错误!"); } this.name = name; } /** * 年龄 */ private Integer age; public Integer getAge(){ LocalDate birthDate = LocalDate.of(1990, 1, 1); Period period = birthDate.until(this.birthday); return period.getYears(); } /** * 出生年月 */ private LocalDate birthday; public LocalDate getBirthday() { return birthday; } public void setBirthday(LocalDate birthday) { this.birthday = birthday; } /** * 地址 */ private Address address; public Address getAddress() { return address; } public void setAddress(Address address){ this.address = address; } }
三、lombok库的使用
在Student例子中,get和set方法的访问修饰符、方法名称、方法体差异都不大,所以通过引入lombok类库来简化相关操作,如下引入依赖项。
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency>
在lombok库中包含相关注解,通过该注解快速实现类的构造器、访问方法get和设置方法set,如@Data、@Builder、@NoArgsConstructor、@AllArgsConstructor、@getter、@setter、Accessors(chain=true)、@Value等。
@Data:@Data是一个复合注解(@Setter、
@Getter、
@ToString、
@EqualsAndHashCode、
@NoArgsConstructor
),使用在类中,会生成默认的无参构造函数、所有属性的getter、所有非 final 属性的 setter 方法、并且重写 toString、equals、hashcode 方法(单独使用@Data注解,是会生成无参数构造方法)。
@Builder:@Builder是比较推荐构建值对象的方式,该描述符表明其将类改造成Builder(建造者)的设计模式,构建类的实例,用在类、方法或者构造函数上(单独使用@Builder注解,是会生成了全属性的构造方法)。
@Value:@Value注解和@Data类似,区别在于会把类的全部成员变量的访问修饰符定义成private final,并且不会生成set()方法。
@NoArgsConstructor:@NoArgsConstructor是会提供无参的构造函数。
@AllArgsConstructor:@AllArgsConstructor是会提供全参数的构造函数,默认public修饰符,要修改修饰符使用(access = AccessLevel.PROTECTED)属性设置。
@RequiredArgsConstructor:@RequiredArgsConstructor是会提供构造函数(带参数或不带参数),带参数则参数必须是以 final 修饰的未经初始化的字段或者是以 @NonNull 注解的未经初始化的字段,还可以使用staticName选项生成指定名称的static方法,返回一个调用相应的构造方法产生的对象。
@setter:@setter会生成相应的set设置方法,要修改修饰符使用(access = AccessLevel.PROTECTED)属性设置。
@getter:@getter会生成相应的get访问方法。
@Accessors(chain=true):Accessors(chain=true)是为类的setter方法提供链式调用,@Accessors(chain=true)
是将生成的 setter()
方法返回 this
,而 @Builder
是再对象内部创建一个构建器,通过这个构建器来最终创建对象。
注意:@Builder 注解会给类默认生成全参构造,这样就没有了默认的无参构造,在Spring这类容器中默认调用无参构造就报错了,所以要加上@NoArgsConstructor
和 @AllArgsConstructor 注解。