List.addAll реплицирует переменные сеанса - PullRequest
2 голосов
/ 16 ноября 2010

В моем классе действий есть следующий код:

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 ]

2 голосов
/ 16 ноября 2010
List sysList = mbr .getSystemList();

Если вы напрямую возвращаете переменную экземпляра списка в MemberData, sysList и MemberData.sysList будут одним и тем же списком.Таким образом, любые изменения в одном из них будут отражены в другом.

Чтобы решить эту проблему, вам нужно создать новый List где-то в вашем коде, лучшее место, вероятно, получатель в MemberData.

1 голос
/ 16 ноября 2010

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'
1 голос
/ 16 ноября 2010

Число 6 в http://www.javacoffeebreak.com/articles/toptenerrors.html объясняет, почему ваши фрагменты кода работают так, как они.

...