6


I am confused in the following:
In C++ we can pass a parameter to a function by reference (having declared it as a pointer or reference variable) and if we modify it inside the function, the changes are reflected to the caller when the function returns.
This is not happening in java and I am not sure I understand why.

E.g. this is a method from an object X

public boolean aMethod(int id, myClass aClass)
{
   //do some logic
   aClass = new MyClass();
   //configure argument object aClass
   return true;
}

In the calling code:

//some code processing
myClass obj = null;
if(X.aMethod(2,obj))
{
  obj.methodA();//start using the object
}

I use it in C++, i.e. to return a result that notifies that the function parameter can be used, but in java this does not work.
I enter the if(X.aMethod(2,obj)) branch but the obj is null. Why is it null?
Haven't I assigned a memory address from the heap using new inside the method aMethod(int id, myClass aClass)? Am I not passing the "address" of obj in the function? I was expecting to have the obj properly constructed and usable in the calling code. Have I misunderstood something concerning memory in java?

Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • 1
    possible duplicate of [what is the difference between pass by reference and call by reference ?](http://stackoverflow.com/questions/3660180/what-is-the-difference-between-pass-by-reference-and-call-by-reference) – David Gelhar Oct 06 '10 at 04:57

6 Answers6

27

Java passes everything by value - including references.

What this means is that if you pass an object, you can modify properties of that object, and they will persist after you return, but you can't replace the object in its entirety with a completely new object, because you can't actually modify the reference - only what the reference points to.

Before your aClass = line:

Outside the function:

    obj ---> <foo>

Inside the function:

    aClass ---> <foo>

After your aClass = line:

Inside the function:

    aClass ---> <bar>

Outside the function:

    obj ---> <foo>

The key thing to notice here is that aClass doesn't point to obj - it points to <foo>. You're not passing the address of obj, you're passing the address of what obj points to. Thus, when you change what aClass points to, that doesn't touch obj.


As an alternative way of thinking about it:

In Java,

Bar foo = new Bar();

is equivalent to C++,

Bar *foo = new Bar();

Thus when you pass foo to a function, you're not passing the address of foo - you're passing the address of the allocated object. Java doesn't have the &-operator style pass-by-reference that C/C++ do.

Amber
  • 507,862
  • 82
  • 626
  • 550
4

Check out my article on this, "Java is Pass By Value, Dammit"

http://javadude.com/articles/passbyvalue.htm

Scott Stanchfield
  • 29,742
  • 9
  • 47
  • 65
3

In C++ what would happen if you did this:

 void myFunct( int * pInt) {
     pInt = // something;
 }

 // caller
 int x;
 int * myPointer = & x;
 myFunc(myPointer);
 // where does myPointer point now? 

the assignment inside myFunc has no effect on the caller's pointer. Now if myFunct took instead pointer to the pointer

 void myFunct( int ** ppInt) {
     *ppInt = // something;
 }

or a reference to the pointer then you would see a change in caller, and that is what I suppose you have been doing.

In Java

 void myFunct (Integere anInteger) {
       // anInteger is  reference to whatever is passed
       anInteger = new Integer(99); // no effect on caller
 }

we do indeed pass references to the function, anInteger above is a reference to an object owned by the caller, but anInteger is a value local to the method assigning to it is the same as assigning to a pInt in the first example, no effect on the caller.

djna
  • 54,992
  • 14
  • 74
  • 117
2

The comment in your example suggest that the method aMethod exists to configure the object. So instead of passing in null, how about instantiating the object first and then pass it in. Alternatively, you can make the method return the object intead, like so:

public boolean aMethod(int id)
{
  myClass aClass = new MyClass();
  return myclass;
}

And:

myClass obj = X.aMethod(2);
if(obj != null)
{
  obj.methodA();//start using the object
}

Alternatively, I prefer to make it a convention that aMethod should always return a valid object. If it's not possible, for example because of a mistake in the configuration, make the method throw an exception instead.

RichN
  • 6,181
  • 3
  • 30
  • 38
1

Java cannot do "pass by reference".

Java uses "pass by value".

Yin Zhu
  • 16,980
  • 13
  • 75
  • 117
  • 2
    You answer does not provide anything new (basically repeating what other people have already said in detail) and also confuses/mislead people. Although Jave uses "pass by value" but people still can change properties of the passed object. However they cannot re-assign a whole new object (what the OP wants to do). – Kamran Bigdely Oct 07 '16 at 00:22
0

consider your object arguments (in Java) passed as such (illustrated in C++):

void method(TObject* arg);
justin
  • 104,054
  • 14
  • 179
  • 226
  • Should be `void method(TObject*& arg);` ? – Ishtar Oct 06 '10 at 10:34
  • @Ishtar no, `void method(TObject*& arg)` is reference to a pointer. arg may be modified (to point to another address) internally, and will be reflected externally -- such that the client's arg could point to another address when `method(arg)` returns. Java passes objects as pointers/by address. Java devs like to call it 'by value', but from a c++ perspective it is passed by pointer (or address), with the language abstracting that fact (and pointers altogether). cont... – justin Oct 06 '10 at 10:44
  • @Ishtar part 2: in c++, pass by value == pass a copy of the object. there is no copy with Java here. so passing a Java object in c++ syntax is analogous to: `void method(TObject* arg);` – justin Oct 06 '10 at 10:47
  • Sorry. I must have misunderstood, my english isn't that good.. Thought you meant something different. Indeed `method(T a)` in java is the same as `method(T * a)` in C++. But, what OP wants to do in the method: `aClass = new MyClass();` requires the `&`. That's what I thought you meant. – Ishtar Oct 06 '10 at 11:03
  • @Ishtar no problem. in fact, my initial response lacks detail - so it's good that it has been clarified now. thanks =) – justin Oct 06 '10 at 11:07