Results 1 to 4 of 4
  1. #1
    gymshoe is offline Member
    Join Date
    Feb 2009
    Posts
    5
    Rep Power
    0

    Default 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

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    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();
    
      }
    }

  3. #3
    gymshoe is offline Member
    Join Date
    Feb 2009
    Posts
    5
    Rep Power
    0

    Default

    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 .

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    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

  1. Problems with a complex datatype in a webservice
    By lichtbringer in forum Web Frameworks
    Replies: 2
    Last Post: 10-29-2008, 06:32 AM
  2. Creating a complex toolbar in SWT
    By Java Tip in forum SWT Tips
    Replies: 0
    Last Post: 07-02-2008, 09:09 PM
  3. Complex Regular Expression HELP
    By hiklior in forum New To Java
    Replies: 1
    Last Post: 04-30-2008, 02:52 PM
  4. Complex proximity Clauses
    By peiceonly in forum Lucene
    Replies: 1
    Last Post: 08-07-2007, 06:43 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •