纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

Java mutable和immutable区别 Java mutable对象和immutable对象的区别说明

zhongrui_fzr   2021-06-10 我要评论
想了解Java mutable对象和immutable对象的区别说明的相关内容吗zhongrui_fzr在本文为您仔细讲解Java mutable和immutable区别的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Java,mutable对象,immutable对象下面大家一起来学习吧

Java mutable对象和immutable对象的区别

今天读jdk源码中Map.java时看到一句话:

great care must be exercised if mutable objects are used as map keys;

第一次知道mutable对象这个概念google了一下维基百科定义如下:

“In object-oriented and functional programming, an immutable object (unchangeable[1] object) is an object whose state cannot be modified after it is created.[2] This is in contrast to a mutable object (changeable object) , which can be modified after it is created. In some cases, an object is considered immutable even if some internally used attributes change but the object's state appears to be unchanging from an external point of view. For example, an object that uses memoization to cache the results of expensive computations could still be considered an immutable object.”

在面向对象和函数式编程中一个immutable对象(不可变对象)是指一旦创建之后状态不可改变的对象

mutable对象(可变对象)是指创建之后也可以修改的对象

在有些情况下对象也被认为是不可变的(immutable)即一个对象包含的内部使用的属性改变了但从外部看对象的状态并没有改变

例如一个使用memoization来缓存复杂计算结果的对象仍然被看作是不可变(immutable)对象.

在面向对象编程中String 以及其他的具体对象都被看作是不可变(immutable)对象以提高可读性和运行效率

不可变对象有几个优点:

线程安全

易于理解

比可变对象有更高的安全性

Java中不可变对象的经典例子就是String类的实例:

String s = "ABC";
s.toLowerCase();

toLowerCase()方法不会改变s中包含的数据“ABC”而是创建一个新的String对象并将其初始化为“abc”然后返回这个新对象的引用

尽管String类声明中没有提供让它成为不可变对象的语法但是String类的方法中没有方法去改变一个String包含的数据这就使得它是不可变的

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

原始数据类型(primitive types)变量(int, long, short等)定义之后还可以再重新赋值可以使用final阻止这样的赋值

int i = 42; //int is of primitive type
i = 43; // OK
final int j = 42;
j = 43; // does not compile. j is final so can't be reassigned

仅仅使用final关键字还不能让引用类型(reference types)成为不可变对象final只能阻止重新赋值

final MyObject m = new MyObject(); //m is of reference type
m.data = 100; // OK. We can change state of object m (m is mutable and final doesn't change this fact)
m = new MyObject(); // does not compile. m is final so can't be reassigned

原始类型包装类(primitive wrappers)(IntegerLong, Short, Double, Float, Character, Byte, Boolean)也都是不可变的

Java mutable 和 immutable类型

含义解释

immutable : variables that are assigned once and never reassigned.

mutable : When you assign to a variable or a field, you're changing where the variable's arrow points. You can point it to a different value. When you assign to the contents of a mutable value – such as an array or list – you're changing references inside that value.

基本类型及其封装对象类型都是不可变的

图形化解释 Snapshot Diagram

mutable:

mutable

immutable:

immutable

举例

例如String和StringBuilder:

1. String是immutable的每次对于String对象的修改都将产生一个新的String对象而原来的对象保持不变

2. StringBuilder是mutable因为每次对于它的对象的修改都作用于该对象本身并没有产生新的对象

如何保证自己创建的类是immutable类

  • 所有成员都是private final
  • 不提供对成员的改变方法setXX
  • 确保所有的方法不会被重写手段有两种:使用final Class(强不可变类)或者将所有类方法加上final(弱不可变类)
  • 如果某一个类成员不是原始变量(例如intdouble)或者不可变类必须通过在成员初始化或者使用get方法时要通过深度拷贝方法来确保类的不可变

优缺点

使用不可变类型对其频繁修改会产生大量的临时拷贝(需要垃圾回收) 

可变类型最 少化拷贝以提高效率

使用可变数据类型可获得更好的性能 也适合于在多个模块之间共享数据 例如全局变量

不可变类型更“安全” 在其他质量指标上表现更好

对可变类型可能造成的风险我们通过防御式拷贝(深度拷贝)给客户端返回一个全新的可变类型的对象大部分时候该拷贝不会被客户端修改 可能造成大量的内存浪费

深度拷贝

当只是引用传递或者根据对象的值创建新的值称为“浅复制”当原对象的发生改变时根据上面方式创建的新对象的也会随之改变

而如果采用深度复制那是真正的复制了一份新的对象新对象的与原对象不存在任何关联原对象发生改变不会影响新对象


相关文章

猜您喜欢

网友评论

Copyright 2020 www.fresh-weather.com 【世纪下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式