当前位置: 首页 > news >正文

25. 能否创建一个包含可变对象的不可变对象

25. 能否创建一个包含可变对象的不可变对象

当然可以,比如 final Person[] persons = new Persion[]{} . persons 是不可变对象的引用,但其数组中的Person实例却是可变的.这种情况下需要特别谨慎,不要共享可变对象的引用.这种情况下,如果数据需要变化时,就返回原对象的一个拷贝。

在 Java 中,可以创建一个包含可变对象的不可变对象,但必须通过防御性设计来确保该对象的不可变性。虽然对象本身不能被修改,但如果其内部引用了可变对象,必须防止这些可变对象的状态被外部修改。

  • 构造函数中进行防御性拷贝(Deep Copy)
    • 在构造函数中对传入的可变对象进行深拷贝,以确保外部修改不会影响到内部状态。例如:
public final class ImmutableWrapper {private final List<String> internalList;public ImmutableWrapper(List<String> list) {this.internalList = new ArrayList<>(list); // 防御性拷贝}
}
  • 返回只读视图(Unmodifiable View)
    • 提供访问内部可变对象的方法时,返回只读视图,防止外部通过接口修改对象状态。例如:
public List<String> getList() {return Collections.unmodifiableList(internalList);
}
  • 不暴露内部引用

    • 不提供任何直接暴露内部可变对象引用的方法,避免绕过只读视图进行修改。
  • 示例代码

以下是一个完整的示例,展示如何创建一个包含可变对象的不可变类:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public final class ImmutableWrapper {private final List<String> internalList;public ImmutableWrapper(List<String> list) {this.internalList = new ArrayList<>(list); // 防御性拷贝}public List<String> getList() {return Collections.unmodifiableList(internalList); // 返回只读视图}public static void main(String[] args) {List<String> mutableList = new ArrayList<>();mutableList.add("Item1");ImmutableWrapper wrapper = new ImmutableWrapper(mutableList);// 外部修改不会影响内部列表mutableList.add("Item2");System.out.println(wrapper.getList()); // 输出: [Item1]// 尝试通过 wrapper 接口修改内部列表try {wrapper.getList().add("Item3"); // 抛出 UnsupportedOperationException} catch (UnsupportedOperationException e) {System.out.println("修改失败: " + e.getMessage());}}
}
http://www.dtcms.com/a/336343.html

相关文章:

  • YOLOV5训练自己的数据集并用自己的数据集检测
  • 2025-08-17 李沐深度学习16——目标检测
  • PAT 1068 Find More Coins
  • ACPI TABLE 方式加载device driver--以spi controller为例
  • 认识信号量机制、以及用信号量来实现进程互斥于进程同步
  • 计算机网络 TCP time_wait 状态 详解
  • VirtualBox-4.3.10-93012-Win.exe 安装教程附详细步骤(附安装包下载)
  • 为何她总在关键时“失联”?—— 解密 TCP 连接异常中断
  • TensorRT-LLM.V1.1.0rc1:Dockerfile.multi文件解读
  • LeetCode 刷题【44. 通配符匹配】
  • 多墨智能-AI一键生成工作文档/流程图/思维导图
  • 《WINDOWS 环境下32位汇编语言程序设计》第3章 使用MASM
  • Redis面试精讲 Day 23:Redis与数据库数据一致性保障
  • 什么是回表?
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘scikit-image’问题
  • Hooks useState的使用
  • leetcode热题100——day33
  • 视频内容提取与AI总结:提升学习效率的实用方法
  • 【深度学习新浪潮】近三年图像处理领域无监督学习的研究进展一览
  • 科目二的四个电路
  • 《Vuejs设计与实现》第 14 章(内建组件和模块)
  • 概率dp|math
  • Android中切换语言的方法
  • 基于Netty的高并发WebSocket连接管理与性能优化实践指南
  • ReactNode 类型
  • 第12章《学以致用》—PowerShell 自学闭环与实战笔记
  • “让机器人更智慧 让具身体更智能”北京世界机器人大会行业洞察
  • Python 调试工具的高级用法
  • OJ目录饿
  • Python 基础语法(二)