Immutable
Immutable
是什么意思?不变的、不发生改变的意思。在JDK
中有很多的类被设计成不可变的,举个大家经常用到的类java.lang.String
,String
类被设计成不可变。String
所表示的字符串的内容绝对不会发生变化。因此,在多线程的情况下,String
类无需进行互斥处理,不用给方法进行synchronized
或者lock
等操作,进行上锁、争抢锁、解锁等流程也是有一定性能损耗的。因此,若能合理的利用Immutable
,一定对性能的提升有很大帮助。
为什么String不可变?
那么为什么String
是不可变的呢?满足那些条件才可以变成不可变的类?大家可以打开String
类的源码:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
/**
* Class String is special cased within the Serialization Stream Protocol.
*
* A String instance is written into an ObjectOutputStream according to
* <a href="{@docRoot}/../platform/serialization/spec/output.html">
* Object Serialization Specification, Section 6.2, "Stream Elements"</a>
*/
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
/**
* Allocates a new {@code String} so that it represents the sequence of
* characters currently contained in the character array argument. The
* contents of the character array are copied; subsequent modification of
* the character array does not affect the newly created string.
*
* @param value
* The initial value of the string
*/
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
/**
* Converts this string to a new character array.
*
* @return a newly allocated character array whose length is the length
* of this string and whose contents are initialized to contain
* the character sequence represented by this string.
*/
public char[] toCharArray() {
// Cannot use Arrays.copyOf because of class initialization order issues
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}
}
通过上边的这段代码你会发现:
1、首先
String
类本身是被final
修饰过的,表明该类无法进行扩展,无法创建子类。因此类中声明的方法则不会被重写。
2、String
类中的成员变量都被final
修饰,同时均为private
,被final
修饰则表示成员变量
不会被setter
方法再次赋值,private
则表示成员变量均为类私有,外部无法直接调用。
3、String
类中的成员变量都没有setter
方法,避免其他接口调用改变成员变量的值。
4、通过构造器初始化所有成员,同时在String
中赋值是用的Arrays.copyOf
等深拷贝方法。
5、在getter
方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝。
以上5点保证String
类的不可变性(immutability
)。
示例程序
下面咱们通过一些简单的示例程序来实验Immutable
,自己动手,丰衣足食,多动手会有好处的。下边定义三个类。
类名 | 说明 |
---|---|
People |
表示一个人的类 |
PeopleThread |
表示People 实例的线程的类 |
Main |
测试程序行为的类 |
下边看下每个类的示例代码,People
类,类以及成员变量均被final
修饰,同时只能通过构造函数来对成员变量赋值,没有setter
方法:
public final class People {
private final String sex;
private final int age;
private f