Java 中如何实现一个像 String 一样不可变类?
如果问你在日常开发中用到的最多的一个 Java
类是什么,阿粉敢打赌绝对是 String.class
。说到 String
大家都知道 String
是一个不可变的类;虽然用的很多,那不知道小伙伴们有没有想过怎么样创建一个自己的不可变的类呢?这篇文章阿粉就带大家来实践一下,创建一个自己的不可变的类。
最新版本 IDEA 破解点这里
程序员限时福利点这里
特性
在手动编写代码之前,我们先了解一下不可变类都有哪些特性,
-
定义类的时候需要使用 final
关键字进行修饰:之所以使用final
进行修饰是因为这样可以避免被其他类继承,一旦有了子类继承就会破坏父类的不可变性机制; -
成员变量需要使用 fina
l 关键词修饰,并且需要是private
的:避免属性被外部修改; -
成员变量不可提供 setter
方法,只能提供getter
方法:避免被外部修改,并且避免返回成员变量本身; -
提供所有字段的构造函数;
实操
知道了不可变类的一些基本特性之后,我们来实际写代码操作一下,以及我们会验证一下,如果不按照上面的要求来编写的话,会出现什么样的问题。
这里我们定义一个 Teacher
类来测试一下,按照我们上面提到的几点,我们给类和属性的定义都加上 final
代码如下所示。
package com.example.demo.immutable;
import java.util.List;
import java.util.Map;
public final class Teacher {
private final String name;
private final List<String> students;
private final Address address;
private final Map<String, String> metadata;
public Teacher(String name, List<String> students, Address address, Map<String, String> metadata) {
this.name = name;
this.students = students;
this.address = address;
this.metadata = metadata;
}
public String getName() {
return name;
}
public List<String> getStudents() {
return students;
}
public Address getAddress() {
return address;
}
public Map<String, String> getMetadata() {
return metadata;
}
}
package com.example.demo.immutable;
public class Address {
private String country;
private String city;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
我们思考一下,上面的代码是否真正的做到了不可变,好,我们思考三秒钟,心里默默的数三下。为了回答这个问题,我们看下下面的测试代码。
package com.example.demo;
import com.example.demo.immutable.Address;
import com.example.demo.immutable.Teacher;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <br>
* <b>Function:</b><br>
* <b>Author:</b>@author Silence<br>
* <b>Date:</b>2022-11-22 21:17<br>
* <b>Desc:</b>无<br>
*/
public class ImmutableDemo {
public static void main(String[] args) {
List<String> students = new ArrayList<>();
students.add("鸭血粉丝 1");
students.add("鸭血粉丝 2");
students.add("鸭血粉丝 3");
Address address = new Address();
address.setCountry("中国");
address.setCity("深圳");
Map<String, String> metadata = new HashMap<>();
metadata.put("hobby", "篮球");
metadata.put("age", "29");
Teacher teacher = new Teacher("Java极客技术", students, address, metadata);
System.out.println(teacher.getStudents().size());
System.out.println(teacher.getMetadata().size());
System.out.println(teacher.getAddress().getCity());
// 修改属性
teacher.getStudents().add("小明");
teacher.getMetadata().put("weight", "120");
teacher.getAddress().setCity("广州");
System.out.println(teacher.getStudents().size());
System.out.println(teacher.getMetadata().size());
System.out.println(teacher.getAddress().getCity());
}
}
为了防止爬虫,请输入验证码提交后查看剩余内容
请关注“Java极客技术”官方微信公众号,回复关键字“bbbb66”,获取验证码。【注】用手机微信扫描右侧二维码或微信搜索公众号“Java极客技术”即可关注哦!
发表评论