List.addAll正在复制会话变量

时间:2010-11-16 12:45:57

标签: java list arraylist session-variables

我的动作类中有以下代码:

MemberData mbr = MyUtil.getMember(request.getSession());
:::::::::::::::::::::::
{
 List sysList = mbr .getSystemList();   //returns 'systemList'
 sysList.addAll(mbr .getUserEnteredList());  //add user entered to the system entered objects list
 addWorksheetFor(wb, sysList);  //add the list to an excel workbook
}

我在会话中有MemberData,它包含一个名为systemList的列表。当我使用List sysList = mbr.getSystemList()然后添加用户输入的列表时,会话对象中的'systemList'被修改。我将两个列表添加到局部变量'sysList'中,但会话变量'systemList'也被修改。它与'sysList'相同。

但是,当我分别遍历systemList和userEnteredList并添加到第三个列表时,如下所示:

MemberData mbr = MyUtil.getMember(request.getSession());
:::::::::::::::::::::::
{
 List sysList = mbr .getSystemList();   //returns 'systemList'
 List userList = mbr .getUserEnteredList();  //returns 'userEnteredList'
 List allList = new ArrayList();
 for (Iterator it=sysList.iterator(); it.hasNext();)
 allList.add(it.next());
 for (Iterator it=userList.iterator(); it.hasNext();
 allList.add(it.next());
 addWorksheetFor(wb, sysList);  //add the list to an excel workbook
}

然后它有效。在这种情况下,会话变量不会被修改。 有什么想法吗?

3 个答案:

答案 0 :(得分:2)

List sysList = mbr .getSystemList();

如果直接返回MemberData中的列表实例变量,则sysList和MemberData.sysList将是相同的列表。因此,对其中一个的任何更改都将反映在另一个中。

要解决此问题,您需要在代码中的某处创建一个新的List,最好的位置可能是MemberData中的getter。

答案 1 :(得分:1)

http://www.javacoffeebreak.com/articles/toptenerrors.html中的数字6解释了为什么您的代码段按照他们的方式工作。

答案 2 :(得分:1)

当您获得正如您所期望的引用时,Java不会返回值(实例)的副本。它返回相同的值(实例)。这被称为按值传递,对于具有过程编程语言背景的程序员(例如PHP)来说确实令人困惑。

您最好的选择是创建一个 new 值(实例)。然而,您尝试的方式有点笨拙,可以简化如下:

List sysList = mbr.getSystemList();   // returns 'systemList'
List userList = mbr.getUserEnteredList();  // returns 'userEnteredList'
List allList = new ArrayList(sysList); // creates a copy of 'sysList'
allList.addAll(userList); // adds 'userList' to copy of 'sysList'