[java] Java References for a C++ guy

Started by
10 comments, last by Thygrrr 19 years, 4 months ago
Hello! Coming from C++, I have a slight problem understanding what exactly in Java is a reference to, and what is an instance of an object. Assuming I have class foo, and class bar, the latter having a constructor bar(foo teh_foo), where I can pass a _____________ (insert what it is - instance, reference, ...) of foo to the new object to work with. So I have:

foo my_foo = new foo(); //EDIT: Forgot to initialize... :p

bar my_bar = new bar(my_foo);
What is passed to the constructor? An exact bitwise copy of my_foo (maybe using a copy constructor?), a reference to my_foo, or something else? Is there an equivalent to the "&" in Java? e.g. bar(foo& teh_foo)...? On a technical note, as I'm mostly working with J2ME at the moment, how much of a memory footprint have those references/instances/... and what are their overheads (GC ref counts, virtual method tables, ...)? Thanks in advance! PS: And oh, who else besides me thinks that Java is in desperate need of some means of operator overloading? Is there a way to pull it off? (looking at java.util.Vector, my hopes somewhat dwindled...) [Edited by - Thygrrr on November 20, 2004 6:58:23 AM]
Advertisement
Well, what you have done in your code is passing in a null reference in the constructor.

Java doesn't have copy constructors per se - they have the clone method. But note that this clone method has some subleties that can mess with your head. Go read Effective Java by Joshua Bloch. He discusses this particular issue. In effect you should make a factory method or, tada: a copy constructor (so now we've come full circle :)).

So a Java reference is not like neither a C++ reference or a C++ pointer. An accurate description it to say that a Java reference paramter is an object reference that's passed by value.
"We confess our little faults to persuade people that we have no large ones." -Francois de La Rochefoucauld (1613 - 1680). | My blog
To continue:

The following piece of code is a nice demonstration of what a Java reference really is, and that the object references get passed by value.

The Box class is a class with a value integer field. The code is as follows:

static void passTest(Box i){  i.value++;  i = new Box(7);}public static void main(String[] args){  Box j = new Box(5);  passTest(j);  System.out.println("J is " + j.value);}


So the question is, what gets printed in the console?
"We confess our little faults to persuade people that we have no large ones." -Francois de La Rochefoucauld (1613 - 1680). | My blog
Java never makes an exact bitwise copy of an object. Objects are always passed by reference, primitive types are always passed by value.
Why do my programs never work on other computers?
So If I get it right, even despite the object's instance passed as an argument being passed by reference, it is treated as 'by value', meaning changes made to the instance passed as the argument won't last beyond the scope of the current function?

So then, there has to exist a bitwise copy somewhere (on the stack), right?

The following code would hence yield "my_foo.x is 5" ...!?


public class foo{  public int x = 5;}...public class bar{  bar(foo teh_foo)  {     teh_foo.x=7;  }}...public class main{  foo my_foo = new foo();  bar my_bar = new bar(my_foo);  System.out.println("my_foo.x is " + my_foo.x);}
Not quite. It prints "my_foo.x is 7".

All Java objects live on the heap. And objects don't get passed around. Ever. What get passed around is the references to them. And they get passed around in a passed by value manner.

The example I had earlier would print "J is 6".
"We confess our little faults to persuade people that we have no large ones." -Francois de La Rochefoucauld (1613 - 1680). | My blog
I will walk through the code example I showed you earlier.

I will just reshow the code here:

static void passTest(Box i){  i.value++;  i = new Box(7);}public static void main(String[] args){  Box j = new Box(5);  passTest(j);  System.out.println("J is " + j.value);}


Let's walk through this a line at a time and discuss what's on the heap.

We start in the main function.

The first line says:

Box j = new Box(5);

This constructs a Box object on the heap and let the j reference point to it. The memory looks like this afte this statement has been executed:

STACK:             HEAP:                   +------------+                   |BOX object  |                   | value=5    | j --------------->|            |                   +------------+

So our j reference on the stack points to a Box object on the heap with it's value field sat to 5.

The next line is:

passTest(j);

So no we enter the passTest function. Here the j reference gets passed by value to the i paramter in the passTest function (but the Box object lies on the heap and doesn't move).

So after entering the passTest function our memory looks like this:
STACK:             HEAP:                   +------------+                   |BOX object  |                   | value=5    | j --------------->|            | i --------------->+------------+

What has happened now is that both the i and the j reference points to the same object on the heap (of course the j reference is out of scope, but it still points to the object).

The first line in the passTest function reads:

i.value++;

So now we alter our box object through our i reference.

Or memory is now:
STACK:             HEAP:                   +------------+                   |BOX object  |                   | value=6    | j --------------->|            | i --------------->+------------+

Next line is:

i = new Box(7);

Now we construct a new Box object and let i point to it. Note that j still points to our old object:
STACK:             HEAP:                   +------------+                   |BOX object  |                   | value=6    | j --------------->|            |                   +------------+                   +------------+                   |BOX object  |                   | value=7    | i --------------->|            |                   +------------+

We now return to our main function (and i goes out of scope), and execute this statement:

System.out.println("J is " + j.value);

Which will of course then print "J is 6".

I hope this helps.

[Edited by - rohde on November 20, 2004 9:33:18 AM]
"We confess our little faults to persuade people that we have no large ones." -Francois de La Rochefoucauld (1613 - 1680). | My blog
Rating++ ! That really helped, I was a little slow to get your point when you first posted the code example.

The reference itself gets passed by value - it makes sense now. Thank you very much, especially for your patience!
Perhaps a little too late—a Java reference is analogous not to a C++ reference (to which Java has no analogue) but to a pointer; all parameter passing passes pointers (by value) except for primitive types, which are passed directly (by value).

Java has nothing like C++ reference parameters.
Quote:Original post by Miserable
Perhaps a little too late—a Java reference is analogous not to a C++ reference (to which Java has no analogue) but to a pointer; all parameter passing passes pointers (by value) except for primitive types, which are passed directly (by value).

Java has nothing like C++ reference parameters.


Yes, C++ pointers and Java references are same in the sense that they both (the Java references themselves and the actual C++ pointers) get passed by value.

But if you would change the example I have outlined above and use C++ pointers the result would be different (it would print "J is 7").
"We confess our little faults to persuade people that we have no large ones." -Francois de La Rochefoucauld (1613 - 1680). | My blog

This topic is closed to new replies.

Advertisement