我的动作类中有以下代码:
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
}
然后它有效。在这种情况下,会话变量不会被修改。 有什么想法吗?
答案 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'