Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jsp session: ArrayList<String> reflects the latest value but for String, it does not

I observed that ArrayList reflects the latest value but for String, it does not

//Initializing List and String
ArrayList<String> list = new ArrayList<String>();
list.add("Item1");
String name = "String1";

//Setting Attribute for both
session.setAttribute("mylist", list);
session.setAttribute("myname", name);

//getting attribute for both
out.println("<br> Printing intial valus <br>");
list = (ArrayList<String>)session.getAttribute("mylist");
for (String s:list){
 out.println(s);
}
name = (String) session.getAttribute("myname");
out.println(name);

//updating the values for both
list.add("Item2");
name = "String2";

//Need to add session.setAttribute again for String
//for it to reflect updated value "String 2"
//session.setAttribute("myname", name);

//getting attribute value after the update
list = (ArrayList<String>)session.getAttribute("mylist");
name = (String) session.getAttribute("myname");

//printing the value for both again
out.println("<br><br><br> Prining updated values <br><br>");
for (String s:list){
 out.println(s);
}
out.println(name);

The output of the below is

Printing intial valus 
 Item1 String1 

 Prining updated values 
 Item1 Item2 String1 Session 2

In the updated values part, shouldn't it print "String2", but for ArrayList it's printing "Item2" as well. If I manually add session.setAttribute("myname", name) just after updating String name values then it prints "String2". But this session.setAttribute is not required for the ArrayList

like image 595
michael Avatar asked Nov 29 '25 06:11

michael


2 Answers

When you pass object as an argument to Java's method - value of its reference copied and passed to it. ArrayList is mutable, so:

List<String> list = new ArrayList<String>();
// copy of object reference passed to session
session.setAttribute("list", list);
// adding new value to same object, so all references to it will see the chages
list.add("Something");

String type is immutable:

// object "value" created, reference passed to 'name' variable
String name = "value";
// copy of reference to object value passed to session
session.setAttribute("string", name);
// NEW object "otherString" created and its reference assigned to variable 'name'
// session still has it's copy of reference to "value" object
name = "otherString";
like image 166
udalmik Avatar answered Dec 01 '25 20:12

udalmik


ArrayList<String> list = new ArrayList<String>();
list.add("Item1");
String name = "String1";

The above lines create a variable named list that points to a location in memory (lets name that locatino LOC123) which has a list element "Item1" You also created a variable named name that points to a location in memory (lets name the locatino LOC456) which has a String value of "String1"

when you passed the name & list variables to the session.setAttribute method you only passed the reference values of the list & name variables. Now the session object is referring to LOC123 & LOC456 in memory, which allows it to retrieve the actual values.

When you executed the list.add("Item2"); command you added one more element to the same memory location LOC123. Given that the session is already pointing to LOC123, you managed to see the changed value reflected.

Java Strings are immutable, you can't change them once they are created. When you executed name = "String2"; you have created a new location in memory LOC789 which has the String value of "String2", and the name variable has now changed to point to LOC789.

Given that the session object still points at LOC456 and given that it knows nothing about LOC789, the updated "String2" value has not been reflected in the session.

To overcome this problem, you could use a StringBuffer (or StringBuilder) which can be edited.

like image 22
H H Avatar answered Dec 01 '25 18:12

H H