Java 中如何实现一个像 String 一样不可变类?

如果问你在日常开发中用到的最多的一个 Java 类是什么,阿粉敢打赌绝对是 String.class。说到 String 大家都知道 String 是一个不可变的类;虽然用的很多,那不知道小伙伴们有没有想过怎么样创建一个自己的不可变的类呢?这篇文章阿粉就带大家来实践一下,创建一个自己的不可变的类。

最新版本 IDEA 破解点这里

程序员限时福利点这里

特性

在手动编写代码之前,我们先了解一下不可变类都有哪些特性,

  1. 定义类的时候需要使用 final 关键字进行修饰:之所以使用 final 进行修饰是因为这样可以避免被其他类继承,一旦有了子类继承就会破坏父类的不可变性机制;
  2. 成员变量需要使用 final 关键词修饰,并且需要是 private 的:避免属性被外部修改;
  3. 成员变量不可提供 setter 方法,只能提供 getter 方法:避免被外部修改,并且避免返回成员变量本身;
  4. 提供所有字段的构造函数;

实操

知道了不可变类的一些基本特性之后,我们来实际写代码操作一下,以及我们会验证一下,如果不按照上面的要求来编写的话,会出现什么样的问题。

这里我们定义一个 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极客技术
为了防止爬虫,请输入验证码提交后查看剩余内容
验证码:
请关注“Java极客技术”官方微信公众号,回复关键字“bbbb66”,获取验证码。【注】用手机微信扫描右侧二维码或微信搜索公众号“Java极客技术”即可关注哦!

评论