0

I came across something that I could not comprehend and never realized it could be done.

I was playing around with this block of code in Android, and what intrigued me was this:

public boolean onTouch(View v, MotionEvent event){
    Rect outRect = new Rect();
    _btn.getHitRect(outRect);
    // ... rest of code cut
    // outRect fields of that Rect object is 'filled' in.
}

How is it that Android's Java can directly modify a Rect object outRect which was passed into the method in order to obtain the Rect of a button widget.

That surprised me, as I thought there was no such thing as 'pass by reference' in Java, in Java parlance, using a 'call-by-reference' rather, its 'pass by value' or 'call-by-value'?

Yes, I have read this question asked before but am stumped, or is that an Android thing?

Can anyone shed some light on this?

Community
  • 1
  • 1
t0mm13b
  • 34,087
  • 8
  • 78
  • 110

5 Answers5

4

The address, in the case of the objects, is a value, the value is copied, analogous to the primitive values. But it's a value which points to an object, and the object is not copied. It exists only once in memory and can be manipulated.enter image description here

User
  • 31,811
  • 40
  • 131
  • 232
  • 1
    This is incorrect; objects are *not* passed. References are passed, and the mechanism is by value. It's more than semantics. – duffymo Jul 07 '12 at 00:13
  • That's what I mean, only expressed it incorrectly, will correct it. – User Jul 07 '12 at 00:18
3

The outRect reference is passed to the getHitRect method, which then modifies the object referred to by outRect. References are passed by value.

For a detailed explanation of this, read this article: http://javadude.com/articles/passbyvalue.htm

Mike Daniels
  • 8,582
  • 2
  • 31
  • 44
  • That's a bit confusing - you say "References are passed by value", in other words a copy? (Good linky by the way - bookmarked - cheers mate) – t0mm13b Jul 07 '12 at 00:10
  • The reference (address) itself is a copy, and as such, it's still the same address. So it points to the same object. – User Jul 07 '12 at 00:11
  • 1
    @t0mm13b That's right! The name "`outRect`" is really the name of a reference to an object. That reference is passed by value (i.e., copied in) to the `getHitRect` method, which then has its own reference to the same object referred to by `outRect`. The important thing to note is that the OBJECT referred to by `outRect` is not being passed, but only a reference to it. – Mike Daniels Jul 07 '12 at 00:12
  • @MikeDaniels Gotcha! Yes, you emphasized the keyword **OBJECT** - that's important... :) Makes sense now! – t0mm13b Jul 07 '12 at 00:15
1

The reference to the Rect object is passed by value but the Rect object itself is allocated on the heap so it can be updated. In effect, this gives you pass-by-reference semantics. However, you cannot change the reference; in other words, something like this won't work:

public void someFunction(Rect r) {
  r = new Rect(); // will not be seen by the calling function
}
Ken Keenan
  • 9,818
  • 5
  • 32
  • 49
1

The highest-rated answer to the question you linked to explains this pretty clearly:

Java is always pass-by-value. The difficult thing can be to understand that Java passes objects as references passed by value.

It then goes on to show two examples that leave no mystery in the behavior you're asking about, unless I've misunderstood what's surprised you.

Darshan Rivka Whittle
  • 32,989
  • 7
  • 91
  • 109
  • Coming from a C/C++ background - that's what surprised me :D but yeah +1 from me even though I read that linked question which kind of left me floundering a bit. :) – t0mm13b Jul 07 '12 at 00:15
1

All parameters to methods in Java are passed by value, both primitives and objects. However, the way objects are referenced in Java is closer to that a C++ pointer than a value. For instance, consider that any object value in Java may take the value null, but in C++ only pointers make take the value null (whereas objects and references* are always valid initialised values).

But what does pass-by-value for an object value actually mean? It means to create a copy of an object and push it onto the stack for the called method to use. Whereas for a pointer it means to push the pointer value onto the stack. That way both the calling and the called method have access to the same memory location where the object value is stored. Thus any changes performed in the called method will be reflected in the calling method.

* There are some instances where a reference may contain corrupt data.

Dunes
  • 37,291
  • 7
  • 81
  • 97