可变对象和不可变对象

简介: 编程语言的对象可变性是值得研究探讨的内容,本文试分析一下可变对象和不可变对象。

可变对象和不可变对象

在面向对象的系统中,存在可变对象(mutable)和不可变对象(immutable)两种对象,本文基于Java语言进行对比分析。

顾名思义,可变对象是创建之后状态可以改变的对象,不可变对象则是创建之后状态不可改变的对象。

一个对象包含的内部使用的属性改变了,但从外部看对象的状态并没有改变,例如一个使用Memoization来缓存复杂计算结果的对象仍然被看作是不可变对象。

不可变对象有几个优点:

  • 线程安全
  • 易于理解
  • 比可变对象有更高的安全性

在面向对象编程中,String以及其他的具体对象都被看作是不可变对象,以提高可读性和运行效率。
尽管String类声明中没有提供让它成为不可变对象的语法,但是String类没有提供方法去改变一个String包含的数据,而是返回一个新的对象,这就使得它是不可变的。

Java字符串不可变的原因:

  1. 字符串常量池的需要:字符串常量池是 Java 堆内存中一个特殊的存储区域,当创建一个 String 对象时,假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。
  2. 允许 String 对象缓存 HashCode:Java 中 String 对象的哈希码被频繁地使用,比如在 HashMap 等容器中。字符串不变性保证了 hash 码的唯一性,因此可以放心地进行缓存。这也是一种性能优化手段,意味着不必每次都去计算新的哈希码。
  3. String 被许多的 Java 类(库)用来当做参数,例如网络连接地址 URL、文件路径 path、还有反射机制所需要的 String 参数等,假若 String 不是固定不变的,将会引起各种安全隐患。

Java中关键字final用于声明原始数据类型和对象引用为不可变对象,但是它不能使对象本身变为不可变对象。

  • 原始数据类型变量(int, long, short等)定义之后还可以再重新赋值,可以使用final阻止这样的赋值。
  • 仅仅使用final关键字还不能让引用类型(reference types)成为不可变对象,final只能阻止重新赋值。

原始类型包装类(Integer、Long、Short、Double、Float、Character、Byte、Boolean)也都是不可变的。

说明

本文首发于CSDN,为博主本人创作,修改后搬运至阿里云开发者社区发表。

相关文章
|
6月前
|
存储 Java 编译器
|
2月前
|
Python
列表的可变性
列表的可变性
创建一个对象用什么运算符?对象实体与对象引用有何不同?
创建一个对象用什么运算符?对象实体与对象引用有何不同?
|
3月前
|
存储 JavaScript 前端开发
对象的属性方法和深浅拷贝
总结,理解对象的属性和方法对于编程是基础而重要的,而掌握深浅拷贝的差异和使用场合则是编程的高级技能,它能帮助你有效地管理数据的完整性和独立性。
19 0
|
11月前
|
Python
Python中的深复制与浅复制:正确处理可变对象
在Python编程中,复制对象是一种常见的操作,而深复制和浅复制是两种不同的复制方式,尤其在处理可变对象时,选择正确的复制方式至关重要。本文将深入讨论深复制和浅复制的概念,并提供一些正确处理可变对象的实用技巧。
|
存储 索引
数组和对象有什么区别?
数组和对象有什么区别?
79 0
|
存储 JavaScript 前端开发
什么是数组,什么是对象,他们的区别是什么
什么是数组,什么是对象,他们的区别是什么
62 0
|
开发工具 索引 Python
可变对象与不可变对象
前阵子我们聊了下函数的参数传递以及变量赋值的一些内容:关于函数参数传递,80%人都错了。
|
索引 Python 容器
继续打脸水货教程:关于可变对象与不可变对象
前阵子我们聊了下Python中有关函数参数传递以及变量赋值的一些内容:Python到底是引用传递还是值传递?网上大多数教程都讲错了
|
存储 Java Python
Python不可变对象与可变对象
Python语言是一个以**一切皆对象**的面向对象的动态型语言。Python的对象可以根据其是否可以变化划分为可变对象和不可变对象。