java学习历程:关于构建不可变对象

关于不可变对象,在《JAVA并发编程实战》中有个例子一直不能理解,如下图

java学习历程:关于构建不可变对象_第1张图片

为什么这个是不可变对象?换个问法,为什么书中提到

博主想了一晚上也没搞明白这句话的含义,直到博主又想起了被java值传递概念支配的恐惧,便写了下面的几行小代码验证猜想:

//尝试构建不可变类
class Object2{
	private final int[] myArray;
	public Object2(int[] myArray) {
		this.myArray = myArray;//此法不可以构建不可变对象,记住值传递,传递的是数组地址,数组变了,对象也变了
	}
	@Override
	public String toString() {
		return "Object2 [myArray=" + Arrays.toString(myArray) + "]";
	}
}

class Object3{
	private final int[] myArray;
	public Object3(int[] myArray) {
		this.myArray = Arrays.copyOf(myArray, myArray.length);//此法不可以构建不可变对象,记住值传递,传递的是数组地址,数组变了,对象也变了
	}
	@Override
	public String toString() {
		return "Object3 [myArray=" + Arrays.toString(myArray) + "]";
	}
}

public class ValuePass {
	public static void main(String[] args)throws Exception{
		//尝试Object2不可变性的测试
		int[] arr = new int[]{1,2};
		Object2 obj2 = new Object2(arr);//传递的是数组的地址(堆地址)
		System.out.println(obj2);
		arr[0]= 2;//改了	
		System.out.println(obj2);//此处也会变化,这就不是不可变对象了

		
		//尝试Object3不可变性的测试
		int[] arr2 = new int[]{1,2};
		Object3 obj3 = new Object3(arr2);//传递的是数组的地址(堆地址)
		System.out.println(obj3);
		arr2[0]= 2;//改了	
		System.out.println(obj3);//此处不会变化,这就是不可变对象了,因为之前已经copy过了,即在堆中构建了新的对象*/
		
	}
}

 输出如下:

由输出可以看出一些东西,由于值传递的原因,若修改值传入的地址所在数组的内容,会导致对象也会发生变化,而只传入copy数组的话相当于创建了一个新的数组,修改原数组自然不会对地址造成影响了,即可认为若构造函数时使用匿名数组也可达到不可变性的目的,科科~

你可能感兴趣的:(小白,java)