​ 这几天有在读一些关于并发的书,然后在一本书上看到了这么一个描述:在Java中,Integer属于不变对象,也就是对象一旦被创建,就不可能被修改。这段描述是讲Integer的对象,当初始化之后这个对象的内容就不能够改变了,对Integer的操作,都会新建一个对象。
换句话讲,Integer对象与Streing表现出来的性质是一样的。然后了解了一下,发现在Java中,不仅仅是Integer类,Double、Float等类都是不可变的。然后我测试了一下基本类型的不变性。

自动包装

​ Java中存在着这么一个机制:int、double、float等都是一些声明变量的关键字,通过这些关键字进行声明的变量,会在实际处理的时候自动封装成为包装器类型。也就是说,int变量会被包装Integer,同理double和float等也会进行相应处理。

不变性的测试

​ 在包装器类型中,声明的对象是不可变类型,那么声明的基本数据类型是不是也是不可变的,我测试了一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
public class AutoPackageTest {

public static void main(String[] args) {
integerTest();
longTest();
doubleTest();
floatTest();
}

public static void integerTest(){

System.out.print("This is IntegerTest:");

Integer integer = 1;
Integer integerU = integer;

int a = 1;
int b = a;

a++;integer++;

System.out.print(integer + " ");
System.out.print(integerU + " ");
System.out.print(a+ " ");
System.out.println(b);
}

public static void longTest(){

System.out.print("This is LongTest:");

Long aLong = 1L;
Long aLongU = aLong;

long a = 1L;
long b = a;

aLong++;a++;

System.out.print(aLong + " ");
System.out.print(aLongU + " ");
System.out.print(a+ " ");
System.out.println(b);
}

public static void doubleTest(){

System.out.print("This is DoubleTest:");

Double c = 1D;
Double d = c;

double a = 1D;
double b = a;

c++;a++;

System.out.print(c + " ");
System.out.print(d + " ");
System.out.print(a+ " ");
System.out.println(b);
}

public static void floatTest(){

System.out.print("This is FloatTest:");

Float c = 1F;
Float d = c;

float a = 1;
float b = a;

c++;a++;

System.out.print(c + " ");
System.out.print(d + " ");
System.out.print(a+ " ");
System.out.println(b);
}
}

​ 运行上述程序,产生的结果是这样的:
Java中的不可变基本类型
也就是说,通过基本数据类型定义的变量,实际上也会产生一个不可变对象,在经过操作之后,也是通过新建一个新的对象来实现的。
所以在实际应用过程中,对基本类型或者自动包装类型加锁的时候,要注意加锁的对象,是不是当前的实例,新建对象的创建可能会造成加锁对象的改变。