Results 1 to 4 of 4
- 08-12-2009, 11:50 PM #1
Member
- Join Date
- Feb 2009
- Posts
- 5
- Rep Power
- 0
I don't understand: a=1;b=2;a=b;a=4 results in b=4 (in complex cases w/ iterator)
I do not understand how java handles variable assignments, sometimes.
I am not even sure how to describe the process which is confusing me, but it appears that if I have set variable a=b and change the value of a, then it will sometimes change the value of b (Example B below), in certain circumstances.
EXAMPLE A:
String a="1";
String b="2";
System.out.println("before assignments");
System.out.println("a="+a);
System.out.println("b="+b);
a=b;
a="4";
System.out.println("after assignments");
System.out.println("a="+a);
System.out.println("b="+b);
OUTPUT:
before assignments:
a=1
b=2
after assignments
a=4
b=2
In this example, there is no reassignment of the value of b when I reassign the value of a, and this behaved as I would have expected.
However, if instead I use a complex class with an Iterator, then I get unexpected results. Specifically:
EXAMPLE B:
class TestClass{
int a;
String str;
TestClass(int i, String _str){
a=i;
str=_str;
}
void displayTestClass(){
if ((Integer)a==null) {
System.out.println("a=null");
} else {
System.out.println("a="+a); }
if (str==null) {
System.out.println("str=null");
} else {
System.out.println("str="+str);
}
}
}
ArrayList<TestClass> al = new ArrayList<TestClass>();
TestClass testClassVar = new TestClass(1, "test1");
al.add(testClassVar);
System.out.println("using TestClass - complex class");
System.out.println("before assignments: ");
al.get(0).displayTestClass();
TestClass testClassVar2 = new TestClass(2,"test2");
Iterator<TestClass> itr = al.iterator();
while (itr.hasNext()) {
testClassVar2 = itr.next();
testClassVar2.str = "insert";
}
System.out.println("after assignment");
al.get(0).displayTestClass();
OUTPUT:
using TestClass - complex class
before assignments:
a=1
str=test1
after assignment
a=1
str=insert
In this example, setting testClassVar2 = itr.next() has then resulted in the "odd" situation that changing a field in testClassVar2 then reflects back to the value of the arrayList iterated item. This I don't understand. :confused:
If I try this using a "simple" ArrayList<String>, I do not see this behavior:
EXAMPLE C:
ArrayList<String> als = new ArrayList<String>();
als.add("initial");
System.out.println("using ArrayList and Iterator with simple strings");
System.out.println("before assignments: ");
System.out.println("als[0]="+als.get(0).toString());
Iterator<String> itrStr = als.iterator();
String dummyStr = new String();
while (itrStr.hasNext()) {
dummyStr = itrStr.next();
dummyStr = "new";
}
System.out.println("after assignment");
System.out.println("als[0]="+als.get(0).toString());
OUTPUT:
using ArrayList and Iterator with simple strings
before assignments:
als[0]=initial
after assignment
als[0]=initial
I would like to know more about what is happening in Example B (which I don't understand), which is different from the behavior in the other examples (which I do understand). Does this process have a name, so I can research it and learn more? How would I best go about understanding when this kind of thing will happen?
Thanks,
Jim
-
This all has to do with what a reference variable is and what an object is. In your first ArrayList Test, you take the object held by the arraylist and place it into a reference variable. This variable refers to the same object that is held by the arraylist. If you change a field of the object referred to by the variable, the arraylist's object will show the changes.
In the second situation, your reference variable initially refers to the String object that is held by the ArrayList, but then refers to a new string. Your pointing this variable to another object, but you don't change the object that it originally held in any way.
this would be analogous to doing this in your first arraylist example:
Java Code:import java.util.ArrayList; import java.util.Iterator; class TestClass { int a; String str; TestClass(int i, String _str) { a = i; str = _str; } void displayTestClass() { if ((Integer) a == null) { System.out.println("a = null"); } else { System.out.println("a = " + a); } if (str == null) { System.out.println("str = null"); } else { System.out.println("str = " + str); } } public static void main(String[] args) { ArrayList<TestClass> al = new ArrayList<TestClass>(); TestClass testClassVar = new TestClass(1, "test1"); al.add(testClassVar); System.out.println("using TestClass - complex class"); System.out.println("before assignments: "); al.get(0).displayTestClass(); TestClass testClassVar2; Iterator<TestClass> itr = al.iterator(); while (itr.hasNext()) { testClassVar2 = itr.next(); testClassVar2 = new TestClass(2, "test2"); } System.out.println("after assignment"); al.get(0).displayTestClass(); } }
- 08-13-2009, 12:43 AM #3
Member
- Join Date
- Feb 2009
- Posts
- 5
- Rep Power
- 0
Thank you. Your explanation was clear and understandable (although not intuitive to me yet) and fast!
It would seem that this kind of behavior can only occur when you are reassigning fields within a reference variable of a class which has fields, since reassigning the reference variable itself then just points it to a different object...
Thanks again.
Jim .
-
You're welcome. You will also see this same behavior when passing reference objects as parameters to a method. Change the object itself and it will be reflected in the original object. Set the parameter = to a new object and there will be no effect on the original object.
Similar Threads
-
Problems with a complex datatype in a webservice
By lichtbringer in forum Web FrameworksReplies: 2Last Post: 10-29-2008, 05:32 AM -
Creating a complex toolbar in SWT
By Java Tip in forum SWTReplies: 0Last Post: 07-02-2008, 08:09 PM -
Complex Regular Expression HELP
By hiklior in forum New To JavaReplies: 1Last Post: 04-30-2008, 01:52 PM -
Complex proximity Clauses
By peiceonly in forum LuceneReplies: 1Last Post: 08-07-2007, 05:43 PM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks