日期:2014-05-20  浏览次数:20805 次

ArrayList作为方法返回值时

public class Test {

/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub

ArrayList<String> list = new ArrayList<String>();
 list.add("001");
 list.add("002");
 
        Student s = new Student("Tom", list);
        
        String name = s.getName();
        name  = "Jerry";
        System.out.println(s.getName());
        
        ArrayList<String> anotherList = s.getCourses();
        anotherList.add("999");
        System.out.println("Tom's course.length = " + s.getCourses().size());
}

}

初始化一个Student对象s,给s赋予一个名字“Tom”和一个ArrayList,这里的ArrayList含有两项内容001和002.之后我通过s.getName取得了s的名字,然后将名字Tom修改为Jerry,最后通过s.getName()打印对象s的名字,此时对象s的名字依旧是Tom。接下来,以同样的方法,通过s.getCourses来获得对象s的ArrayList,然后给ArrayList添加一项999,然后打印出对象s的ArrayList的大小,此时对象s的ArrayList的大小是3.
我的问题来了:前者修改名字后,因为作用于name,而name与对象s的属性name没有关系,因此对于对象s没有任何影响,但是,为什么后者修改ArrayList时,对象s的ArrayList的大小会有变化?我修改的是anotherList,难道这里的anotherList指向了对象s的ArrayList?

------解决方案--------------------
在看《重构——改善既有代码的设计》吧,关键在于你 getCourses(); 方法的定义中返回的是 Student 类   Courses,而 Courses 正是 list 所指向的值

------解决方案--------------------
String 是final类,不可改变。 你那个根本就没对s的name赋值,你用s.name=xxx试试肯定会变
List是引用的,获得到之后add肯定size变3
------解决方案--------------------
就像是你自己说的一样:
我修改的是anotherList,难道这里的anotherList指向了对象s的ArrayList?—— Yes

Java数据类型分基本类型和引用类型,所有的对象都是引用类型,anotherList和s.getCourses()获取的list其实都是引用,都指向真实的数据。

再深入说,就是对象的内存是分配在堆区的(你可以理解堆区有块内存存储了真实数据)。anotherList是引用,在栈区,指向堆区的真实数据。