27

Say we have an ArrayList myArray. I want to modify an object by calling its function. If I do it this way, will the original object be changed or not?

myArray.get(0).myModyfyingFunction();

To clarify further - I am concerned if get() actually returns a reference to my original object or does it only return a copy of my original object.

tshepang
  • 12,111
  • 21
  • 91
  • 136
c0dehunter
  • 6,412
  • 16
  • 77
  • 139
  • 7
    Why don't you try it out.. :) It's a few lines of code... – PrimosK Mar 19 '12 at 17:15
  • 2
    Check out this article: http://www.javaranch.com/campfire/StoryPassBy.jsp (The whole cat remote control in a cup concept is awesome) – Francisco Paulo Mar 19 '12 at 17:20
  • Good point there @PrimosK :) I guess I wanted to hear the explanations as well as I've read that Java is pass-by-value only. – c0dehunter Mar 19 '12 at 17:30
  • 2
    @PrimožKralj -It is confusing if you look at java with a C back ground in context of pass-by-value and pass-by-reference. From a C stand point everything in Java is pass-by-value. But Java works on `object references`. Look [here](http://mindprod.com/jgloss/parameters.html) for better idea. – ring bearer Mar 19 '12 at 17:35
  • Thank you ring bearer. Also thanks to Francisco, I've read the JavaRanch article and it relly makes sense now. And I laughed too, great choice of words :) – c0dehunter Mar 19 '12 at 17:39

7 Answers7

68

get() will return a reference to the object, never a copy. Any modification you do on the returned reference will be made on the object itself

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • Thank you, I've read a whole lot of blogs where it says that objects in Java are always passed by value and that's why I am confused. – c0dehunter Mar 19 '12 at 17:27
  • 5
    That's true, all objects are passed by value. The confusing part is, that _references_ are also passed by value - meaning that when you add an object to an ArrayList you end up with two references pointing to the same object, and if you modify one reference, the "other" will also get modified, because both are pointing to the same object – Óscar López Mar 19 '12 at 17:38
  • 2
    @PrimožKralj: "objects" are not values in Java. Objects are never passed or assigned. You are assigning and passing references, always by value – newacct Mar 19 '12 at 21:58
7

If you store any object in ArrayList, Object is not replicated and any change in object should reflect in object itself.

for example we have class NewClass

  public class NewClass {

private String mystring="";

/**
 * @return the mystring
 */
public String getMystring() {
    return mystring;
}

/**
 * @param mystring the mystring to set
 */
public void setMystring(String mystring) {
    this.mystring = mystring;
}

}

here is code in main method of any other class

   List<NewClass> newclasses = new ArrayList<NewClass>();
    NewClass class1 = new NewClass();
    class1.setMystring("before1");
    NewClass class2 = new NewClass();
    class2.setMystring("before2");
    newclasses.add(class1);
newclasses.add(class2);
newclasses.get(0).setMystring("after1");
System.out.println(class1.getMystring());

This will output after1.

kundan bora
  • 3,821
  • 2
  • 20
  • 29
3

This depends on what kind of object you stored in your ArrayList. For example, if they are java.lang.String s, the calls will not modify anything. Otherwise, yes it will modify your object stored at index 0.

ring bearer
  • 20,383
  • 7
  • 59
  • 72
  • Good point about the implementation of the method, but I think in this case we can assume it will actually modify the instance it was called on. :) – Thomas Mar 19 '12 at 17:23
  • 1
    it does not depend on what kind of object it is. It just depends on what the method does. String just happens to not have any methods that mutate it – newacct Mar 19 '12 at 21:59
  • @newacct So, doesn't that necessarily mean "what kind of" object is in it? – ring bearer Mar 19 '12 at 23:22
1

Java never returns copies of objects, only copies to references of objects. Thus the method would definitely change the object at index 0.

You could get a "copy" of an object if the method would create one, e.g. by using return object.clone(); if possible, but what is actually returned is a reference to the copy that was still created in the method. So you could get a "copy" of an object in a broader sense, but ArrayList#get(...) won't do that - and by convention neither getter should do that unless explicitly stated.

Thomas
  • 87,414
  • 12
  • 119
  • 157
1

It gives you a reference to the object so if your function performs any modification in its state, your object will be modified.

Same happens when you do this:

ArrayList myArray = new ArrayList();
MyObject obj = new MyObject();
myArray.add(obj);
obj.myModifyingFunction();
myArray.get(0).equals(obj); // returns true
myArray.get(0) == obj; // returns true as well
Alonso Dominguez
  • 7,750
  • 1
  • 27
  • 37
  • `myArray.get(0).equals(obj);` might actually even return true if `obj` was not the same instance but only logically equal (depends on the implementation of `equals()`). – Thomas Mar 19 '12 at 17:21
  • good observation, I modified my answer to clarify that the object was modified and it's the same reference that the added one (and it's also logically equal). – Alonso Dominguez Mar 19 '12 at 17:27
  • Thank you for your explanation and provided example. – c0dehunter Mar 19 '12 at 17:28
0

Here is an example. Modify an object of Test class in the List.

public class ModifyArrayList {

    public static void main (String [] args) {

        List<Test> tests = new ArrayList<Test>();

        Test firstTest = new Test();
        firstTest.setId(100);
        firstTest.setName("John");
        tests.add(firstTest);

        Test secondTest = new Test();
        secondTest.setId(101);
        secondTest.setName("Tracy");
        tests.add(secondTest);

        Test thirdTest = new Test();
        thirdTest.setId(102);
        thirdTest.setName("Ryan");
        tests.add(thirdTest);

        ListIterator<Test> testIterator = tests.listIterator();
        while(testIterator.hasNext()) {

            Test test = testIterator.next();
            if (test.getName().equals("Ryan")) {
                test.setId(300);
            }

            testIterator.remove();
            testIterator.add(test);
        }

        for (Test test : tests) {
            System.out.println("Test #" + test.getId() + " name=" + test.getName());
        }

    }
}

Test.java

class Test {

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
rupinderjeet
  • 2,984
  • 30
  • 54
Steer360
  • 544
  • 2
  • 7
  • 14
0

Update objects in list:

for (User user: Users) {
    user.setName( user.getName() + " New Name");
}

Show updated objects

for (User user: Users) {    
    System.out.println( user.getName());
}
rupinderjeet
  • 2,984
  • 30
  • 54