-1

I had a doubt in my code snippet : my main class

public static void main(String[] args) {
    Test test = new Test();
    test.copyAtoB(3);
    test.setValueinAlist(30, 3);
    test.showValues(3, 0);   
    } 

And this my dummy class

public class Test {

    public ArrayList<MyClass> alist = new ArrayList<MyClass>();
    public ArrayList<MyClass> blist = new ArrayList<MyClass>();

    Test() {
    for (int i = 0; i < 10; i++) {
        MyClass myClass = new MyClass();
        myClass.setCount(i);
        alist.add(myClass);
    }
    }

    public void copyAtoB(int position) {
    MyClass o = alist.get(position);
    System.out.println("vlaue of count in object of myclass going to be copied "+o.getCount());
    blist.add(o);
    }

    public void setValueinAlist(int val,int position){
    MyClass myClass= alist.get(position);
    System.out.println(myClass.getCount()+" is changing to "+val);
    myClass.setCount(val);
    }

    public void showValues(int aPostion,int bPosition){
    System.out.println("Vlaue in a "+alist.get(aPostion).getCount()+"\n Vlaue in b "+blist.get(bPosition).getCount());
    }

}

Here comes My object class

public class MyClass {
    int count;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

when i run my code i was expecting output like this

vlaue of count in object of myclass going to be copied 3
3 is changing to 30
Vlaue in a 30
 Vlaue in b 3

But what i'm getting is this

vlaue of count in object of myclass going to be copied 3
3 is changing to 30
Vlaue in a 30
 Vlaue in b 30

Could you help me to understand why my concept is wrong ?? I didn't write code to change the value in "blist" but it also get changed how does this happens ?? May be i'm asking a blunder but i couldn't resist

Hanky Panky
  • 46,730
  • 8
  • 72
  • 95
edwin
  • 7,985
  • 10
  • 51
  • 82
  • java always uses pass by value. This article would help understand it clearly. http://www.thejavageek.com/2013/08/24/pass-by-value-or-pass-by-reference/ – Prasad Kharkar Dec 30 '13 at 04:39

2 Answers2

4

Java is pass-by-value. The value for a variable of an object type is a reference to some object in the system. In your case, you're putting a copy of a reference to each MyClass instance in each list, and then you're using one of those reference values to change the fields of the single object that both lists are pointing to.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • `myClass.toString()` (I assume you mean the default [`Object#toString`](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#toString())) does *not* show you the reference. It shows you an arbitrary string built from the class name and the instance hash code. That's *all* that data is, nothing more. – T.J. Crowder Dec 30 '13 at 04:38
  • @T.J.Crowder For some reason, I had had it in my head that it was built directly from the pointer instead of the `hashCode()`. Thanks for the correction. (That said, the default `hashCode()` is the pointer.) – chrylis -cautiouslyoptimistic- Dec 30 '13 at 04:39
  • Semantics. Conceptually, objects are passed by reference. The whole object (the "value") is not passed. If the "value" being passed is a reference that's close enough to say it's passed by reference. – Bohemian Dec 30 '13 at 04:40
  • @Bohemian I tend to agree with you, but the spec is quite clear on the official Java line on the issue, and "pass by value, and the value is a reference to an object" is the best kind of correct. – chrylis -cautiouslyoptimistic- Dec 30 '13 at 04:41
  • @Bohemian: The term "pass-by-reference" has a specific meaning: Passing a reference to **the variable** into a function/method, so that you can change **the variable**. It's completely unrelated to object references. Saying anything in Java is "pass-by-reference" is always incorrect, and tends to be misleading. If Java had pass-by-reference, you could have an `int n`, make the call `foo(n)`, and `foo` could change the value of `n`. (Or `Object o`, `foo(o)`, and `foo` could point `o` at a *different* object.) That does not exist in Java. – T.J. Crowder Dec 30 '13 at 04:50
1
test.copyAtoB(3);

Takes the reference of the element at index 3 in alist and adds a copy of its value to the front of blist, ie. index 0.

test.setValueinAlist(30, 3);

Takes the reference of the element at index 3 in alist, dereferences it to invoke the setCount method, changing the object's value to 30.

test.showValues(3, 0);   

Gets the references of the elements at indices 3 and 0 of alist and blist respectively, dereferences them to access the referenced object and prints out its value. The references are to the same object.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • So java is reference here ,i'm i right?? By Reference i means pointing to same memory location . Correct me if i'm wrong – edwin Dec 30 '13 at 04:42
  • @edwin Java is pass by value always. It's passing a copy of the the value of the reference. – Sotirios Delimanolis Dec 30 '13 at 04:42
  • so if copy is passed. when i alter reference how copy it will get also reflected ?? – edwin Dec 30 '13 at 04:44
  • @edwin Because you are not altering the reference. You are _dereferencing_ the reference to access the referenced object. – Sotirios Delimanolis Dec 30 '13 at 04:45
  • @edwin You have `Object someRef = ...`. That stores some reference. Doing `someRef.toString()` means dereference `someRef` to invoke the `toString()` method on it. – Sotirios Delimanolis Dec 30 '13 at 04:45
  • So you mean that both my arraylist is pointing to same object right ?? – edwin Dec 30 '13 at 04:59
  • @edwin Yes, they are storing references with the same value, ie. the same object. – Sotirios Delimanolis Dec 30 '13 at 05:00
  • But you mentioned " It's passing a copy of the the value of the reference.".This is confusing me. if its only a copy. why the changes is affecting it too. May be asking a blunder . please explain this – edwin Dec 30 '13 at 05:11
  • @edwin When you have a variable of some reference type, that variable's value is the reference to the object, ie. the object's address in memory. When you pass that variable as a method argument, the corresponding method parameter gets assigned a copy of that value. So the value is the same, but the variables are not. – Sotirios Delimanolis Dec 30 '13 at 05:13
  • @edwin So changing the value of the variable does not affect the other one. This is what is known as pass by value. However, if you dereference the variable, you are still accessing the same object. – Sotirios Delimanolis Dec 30 '13 at 05:16
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44131/discussion-between-edwin-and-sotirios-delimanolis) – edwin Dec 30 '13 at 05:24