Immutable objects are simply objects whose state (the object's data) cannot change after construction.
Examples of immutable objects from the JDK include
String
and
Integer
.
Immutable objects greatly simplify your program, since they :
-
are simple to construct, test, and use
-
are automatically thread-safe
and have no synchronization
issues
-
do not need a copy constructor
-
do not need an implementation of clone
-
allow hashCode
to use lazy initialization
,
and to cache its return value
-
do not need to be copied defensively
when used
as a field
-
make good Map
keys and Set
elements (these objects must
not change state while in the collection)
-
have their class invariant
established once upon construction,
and it never needs to be checked again
- always have "failure atomicity" (a term used by Joshua Bloch) : if
an immutable object throws an exception, it's never left in an
undesirable or indeterminate state
Immutable objects have a very compelling(
令人信服的,有说服力的
) list of positive qualities.
Without question, they are among the simplest and most robust kinds of classes you can possibly build.
When you create immutable classes, entire categories of problems simply disappear.
Make a class immutable by following these guidelines :
- ensure the class cannot be overridden - make the class final
, or
use static factories and keep constructors private
- make fields private
and final
- force callers to construct an object completely in a single step, instead of using a no-argument constructor
combined with(与…结合
) subsequent calls to setXXX
methods (that is, avoid the Java Beans convention
)
- do not provide any methods which can change the state of the object in
any way - not just setXXX
methods, but any method which can change
state
- if the class has any mutable object fields, then they must be
defensively copied
when passed between the class and its caller
In Effective Java
, Joshua Bloch makes this compelling recommendation :
"Classes should be immutable unless there's a very good reason to
make them mutable....If a class cannot be made immutable, limit its mutability as much as possible."
It's interesting to note that
BigDecimal
is technically not
immutable, since it's not final
.
Example
import java.util.Date;
/**
* Planet is an immutable class, since there is no way to change
* its state after construction.
*/
public final class Planet {
public Planet (double aMass, String aName, Date aDateOfDiscovery) {
fMass = aMass;
fName = aName;
//make a private copy of aDateOfDiscovery
//this is the only way to keep the fDateOfDiscovery
//field private, and shields this class from any changes that
//the caller may make to the original aDateOfDiscovery object
fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
}
/**
* Returns a primitive value.
*
* The caller can do whatever they want with the return value, without
* affecting the internals of this class. Why? Because this is a primitive
* value. The caller sees its "own" double that simply has the
* same value as fMass.
*/
public double getMass() {
return fMass;
}
/**
* Returns an immutable object.
*
* The caller gets a direct reference to the internal field. But this is not
* dangerous, since String is immutable and cannot be changed.
*/
public String getName() {
return fName;
}
// /**
// * Returns a mutable object - likely bad style.
// *
// * The caller gets a direct reference to the internal field. This is usually dangerous,
// * since the Date object state can be changed both by this class and its caller.
// * That is, this class is no longer in complete control of fDate.
// */
// public Date getDateOfDiscovery() {
// return fDateOfDiscovery;
// }
/**
* Returns a mutable object - good style.
*
* Returns a defensive copy of the field.
* The caller of this method can do anything they want with the
* returned Date object, without affecting the internals of this
* class in any way. Why? Because they do not have a reference to
* fDate. Rather, they are playing with a second Date that initially has the
* same data as fDate.
*/
public Date getDateOfDiscovery() {
return new Date(fDateOfDiscovery.getTime());
}
// PRIVATE //
/**
* Final primitive data is always immutable.
*/
private final double fMass;
/**
* An immutable object field. (String objects never change state.)
*/
private final String fName;
/**
* A mutable object field. In this case, the state of this mutable field
* is to be changed only by this class. (In other cases, it makes perfect
* sense to allow the state of a field to be changed outside the native
* class; this is the case when a field acts as a "pointer" to an object
* created elsewhere.)
*/
private final Date fDateOfDiscovery;
}
Note that javadoc
1.4
includes the -tag
option, whereby simple custom tags may
be defined. One might define an @is.Immutable
tag, for example,
to document a class as being immutable.
You might also consider defining your own tag interface
for immutable objects.
分享到:
相关推荐
主要介绍了JAVA不可变类(immutable)机制与String的不可变性(推荐)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
Immutable 是 Facebook 开发的不可变数据集合。不可变数据一旦创建就不能被修改,是的应用开发更简单,允许使用函数式编程技术,比如惰性评估。Immutable JS 提供一个惰性 Sequence,允许高效的队列方法链,类似 map...
流行的Java面试题之一是:什么是不可变对象(immutable object),不可变对象有什么好处,在什么情况下应该用,或者更具体一些,Java的String类为什么要设成immutable类型? 不可变对象,顾名思义是创建后不可以...
在 Python 中一切都可以看作为对象。每个对象都有各自的 id, type 和 value。 id: 当一个对象被创建后,它的 id 就不会在改变,这里...常见的不可变对象(immutable objects): Number: int, float, complex string t
ImmutableCollections-基于数组的Java不可变集合 版权所有(c)2017 Nicholas Cull 有关许可信息,请参阅LICENSE.txt。 Java 1.8的基于数组的不可变集合 排序和未排序的变体 风格类似于番石榴收集包装 空友好 Java 8...
immutable - Javascript不可变的持久化数据集合
Java的不可变集合 概述 Java库的不可变集合(JImmutable Collections)是一组高性能的不可变集合,用于替换或补充标准的java.util集合。 为每个最常用的集合提供功能替换: Java类 JImmutable接口 工厂方法 数组...
提供Java不变/持久集合类的库。 尽管集合是不可变的,但它们提供了通过创建自身的新修改副本来添加和... 2-3树和整数trie类针对性能进行了优化,并且在需要不可变性以实现安全数据共享时可以与java.util集合一起使用。
kotlinx.collections.immutable, Kotlin的不可变集合 Prototype Kotlin的不可变集合库 Kotlin的不可变集合接口和实现 Prototype 。有关详细信息,请参阅建议列表。Prototype实现基于 pcollections ( 版权 2015的作者...
dot-prop-immutable, 点prop的不可变版本,带有一些扩展名 dot-prop-immutable 点prop的不可变版本,带有一些扩展名。npm install dot-prop-immutable这个模块的动机是在不改变普通JavaScript对象的现有状态的情况
go-immutable-radix, 在Golang中,一个不可变的基数树实现 go-immutable-radix 提供实现不可变 radix的iradix 包。 包只提供单个 Tree 实现,针对稀疏节点优化。作为一个基数树,它提供以下内容:O(k) 操作。在许多...
#ImmutableObject ImmutableObject 被创建为一种简单的客户端 Javascript 方式来制作不可变对象。 它使用一组简单的方法来获取和设置项目。 仅当您为isExtensible传递true参数时才允许设置项目。 ##基本用法: 可以...
不可变视图-其他集合对象的不可变视图概述immutable-views包提供的集合类是其他(可变)集合对象上的不可变视图: 另一个映射对象的不可变视图。 在另一个列表(序列)对象上的变视图。 在另一个set对象上的变视图。...
guava-19.0-rc2.jar:不可变对象Guava:ImmutableXXX:Collection、List、Set、Map… (jar包下载)
如何使用只需加载build/Immutable.min.js ... 这意味着可变对象仅在它们是完全相同的对象时才相等,但不可变对象在具有相同值时才相等。 这两个可变对象是不同的,因此它们不相等: // falseequal ( { "foo" : 1 } , {
@ polyn / immutable使用本机JavaScript功能(即Object.freeze )使对象不可变。 它使用来验证您定义的架构,并且还支持自定义验证器(即,如果您更喜欢JSON架构)。 与Object.freeze不同,@ polyn / immutable递归...
Kotlin的不可变集合接口和实现原型。
seamless-immutable: 不可变JS数据结构向后兼容常规数组和对象
imobject允许您创建深度不可变JavaScript对象。 设置属性后,将无法添加其他属性,并且无法修改初始属性。 ## Installation要使用 ,请cd进入您的项目目录,并使用npm或yarn安装imobject。 npm $ cd /to/project/...