“持有对象”小记

  关于《Java编程思想》第十一章“持有对象”一个内容的思考

  

  在书中第244页,提到了这样的一个方法:Collection.shuffle() 方法。其功能是打乱一个 List 中的元素的顺序。

  在这一页的下方,举了这样一个例子:

  根据这段代码,如果直接来看,可以这样分析:

    list1引用指向了一个全新的ArrayList,其内容为数组ia的元素。当其调用了Collection.shuffle() 方法之后,就会将元素顺序打乱而不会打乱数组ia的元素顺序。

    对于list2,大概会如此分析:Arrays.asList(ia) 返回了一个List型引用,其内容同数组ia元素相同。这个引用由于是List型,故并不会影响数组ia的元素。也就是说当对list2这个引用调用Collection.shuffle() 方法打乱后,并不会影响ia数组元素内容,但根据这段代码如下结果来看,事实并非如此。   

  也就是说:原来的ia数组元素的顺序也被打乱了!

  那么问题在哪儿?

  问题就在于Arrays.asList()方法返回的引用究竟指向的是哪一块空间。

  考虑到Java中的数组,本质上也是一个引用,故结合测试结果可以推测,这时Arrays.asList()方法是把数组的引用直接作为返回值返回了。所以当list2引用调用打乱的方法时,自然会把数组元素也给打乱了,因为list2引用和ia数组引用指向的空间是一样的。

  因此也就不能认为是因为二者的类型不同使得返回值不同。

  考虑到课上老师讲过的一些情况的分析,可以发现,其实很多时候对于栈和堆的问题还是要注意的。为了安全起见(保证数据不被意外更改),尽量使用像list1方式的传递一个新对象,从而“阻断”这种更改数据的意外。

  当然,书中在245页也提到了这个问题:

    “意识到Arrays.asList()产生的List对象会使用底层数组作为其物理实现是很重要的。”

  所以,时刻保持警惕,认真理解书中的一字一句,总会有一些意外的收获。积少成多,终会理解“Java编程思想”。

原文地址:https://www.cnblogs.com/stevenshen123/p/8571107.html