• Post Reply Bookmark Topic Watch Topic
  • New Topic

Object Reference Variables & the Heap  RSS feed

 
Michael Miller Jr
Greenhorn
Posts: 8
Android Chrome Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The following is a question I posted to my friend (via Facebook) who knows quite a bit about Java. The question posted is in response to the section "Life on the Garbage-Collectible Heap" in the book, "Head First Java", chapter 3.

Let's say you have the following:
Book b = new Book();
Book c = new Book();

Two references, each referencing a respective object.
Then you create a third reference:

Book c = d;

First, do the references act like remote controls in that they actually affect the objects, personally, or does the JVM simply utilize the data from the references in regards to what each object does as it is referenced?

If it's the former, how does it work that two references do not conflict when controlling the SAME object? OR, is it that the two references simply act as their own individual selves AS IF there were actually two separate objects (even though, in fact, there's only one object twice referenced)?

Hope that makes sense. Besides all that, so far I'm getting object reference variables thus far.


This is my friend's reply:
The answer is: this varies by language and circumstances.

What you're really talking about is assignment by value vs. assignment by reference.

In Java, primitive types (think strings, numbers, etc.) are assigned by value.

x = 5;
y = x;

If you change y, it does not change the value of x, and vice versa--because they are assigned by value, not reference.

But suppose we are using your Book objects.

Book c = d;

This does not actually make a copy of "d". Instead, it says "take the memory location of object d, and assign it to object c." If you modify c or d, then the other object will also show those changes. What you think of as an object (the variables b, c, and d) is actually just a pointer to a memory location.

If, instead, you want c to be its own independent copy of d, you would use the "clone" method:

Book c = d.clone();

(Note that you may have to implement a "clone" method in the Book class to support this.)


Unfortunately, I don't know that my friend answered my question clearly enough for me. On one hand, I get the explanation, but I'm still confused about the nature of a reference variable in how it relates to the object it is associated with. Especially when you have two references to the same object. For that matter - and perhaps this will be better explained later in the book - why would you want two references to the same object when changing the values in the reference will affect the other reference equally?

I'd definitely appreciate some clarification, please. Thanks!
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Michael Miller Jr wrote:The following is a question I posted to my friend (via Facebook) who knows quite a bit about Java. The question posted is in response to the section "Life on the Garbage-Collectible Heap" in the book, "Head First Java", chapter 3.

Let's say you have the following:
Book b = new Book();
Book c = new Book();

Two references, each referencing a respective object.


References don't contain objects. They refer to, or "point to" them.


Then you create a third reference:

Book c = d;

I assume you mean Book d = c; I'm going to continue my answers based on that assumption.

First, do the references act like remote controls in that they actually affect the objects, personally, or does the JVM simply utilize the data from the references in regards to what each object does as it is referenced?

No idea what that question is supposed to mean. However, what Book d = c; does is copy the reference value from variable c into variable d, so that now both variables "point to" the same Book object.

If it's the former, how does it work that two references do not conflict when controlling the SAME object?


What kind of conflict to you think there would be? Imagine you're holding two remotes that control the same TV. You use one to change the channel and the other to adjust the volume. So what? The TV doesn't know or care. All that matters to it is that it got one message about the channel and another message about the volume. It doesn't care where the messages came from, and the remotes don't know or care if some other remote is sending messages.

Now, on the other hand, if you're pushing buttons on both remotes at the same time then that could, in theory, leave the TV in an invalid or inconsistent state. This is multithreading, and we prevent these problems by using synchronization and the higher level constructs in java.util.concurrent.*. The end result of proper handling of this situation is essentially as if a remote needs a special dongle stuck into it before it can operate, and there's only one dongle per TV. However, that is a very loose analogy, and it doesn't really accurately portray the picture. (I've never really cared for the "remote" analogy in the first place.)

The answer is: this varies by language


Well, yes, it definitely varies by language. We're talking about Java here though.


What you're really talking about is assignment by value vs. assignment by reference.


No, I don't think so. I don't think those terms apply to Java, and I don't know if they even have a standard meaning.

In Java, primitive types (think strings, numbers, etc.) are assigned by value.


No. First, Strings are not primitives. Second, all assignments in Java are the same at the core of it: The value of the expression on the RHS is evaluated, and that value is copied into the variable on the LHS.


But suppose we are using your Book objects.

Book c = d;

This does not actually make a copy of "d". Instead, it says "take the memory location of object d, and assign it to object c."


No.

The value in d is copied into c. That value is a reference, not an object. A variable never holds an object in Java.

Also, memory location has nothing to do with it. That's not part of the spec (although it will, in some form, almost certainly be part of any implementation.

Details here: http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.26.1


If you modify c or d, then the other object will also show those changes. What you think of as an object (the variables b, c, and d) is actually just a pointer to a memory location.




Depends what you mean by "modify c or d". There is no "other object". There's only one object, and both c and d refer to it. If by "modify c or d" you mean "change the value of the c or d variable, such as c = somethingElse;" then the other variable will not be affected. If, on the other hand, you're talking about changing the state of the object that c and d both point to, then both c and d will see those changes.

And, again, the JLS doesn't say anything about "memory locations" as far as I know.

If, instead, you want c to be its own independent copy of d, you would use the "clone" method:

Book c = d.clone();
(Note that you may have to implement a "clone" method in the Book class to support this.)


That's one way. The clone() method is often frowned upon, however. Copy constructors are the other common approach.

Note, however, that that's now how you get a copy of "d". "d" is just a variable, and you can get a copy of it with c = d; a explained above. The clone() method or a copy constructor is how you copy an object (that a reference variable points to).

For that matter - and perhaps this will be better explained later in the book - why would you want two references to the same object when changing the values in the reference will affect the other reference equally?


There are various cases where it's useful. For instance, if parameters are passed to a method or constructor, and you want to copy them to a member variable. The parameter ceases to exist when the method ends, but the member variables lives as long as the object does:


 
Michael Miller Jr
Greenhorn
Posts: 8
Android Chrome Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, so much!
That was a great deal of help. Still gonna take me a bit to get my mind wrapped around it all, but I believe I understood what you meant for the most part.

References don't contain objects. They refer to, or "point to" them.

Right. That's basically what I was saying. I understood that much so far from the book.

I assume you mean Book d = c; I'm going to continue my answers based on that assumption.

*chuckles* You assumed correctly. Sorry about that.

First, do the references act like remote controls in that they actually affect the objects, personally, or does the JVM simply utilize the data from the references in regards to what each object does as it is referenced?
No idea what that question is supposed to mean. However, what Book d = c; does is copy the reference value from variable c into variable d, so that now both variables "point to" the same Book object.

Sorry for the confusion - it's hard to explain what I'm confused about when I'm still working on being sure about what does seem to make sense. To top it off, I'm still learning how the JVM "thinks" and does things behind the scenes and all. But you seemed to grasp what I was trying to get at... Thank you.

What kind of conflict to you think there would be? Imagine you're holding two remotes that control the same TV. You use one to change the channel and the other to adjust the volume. So what? The TV doesn't know or care. All that matters to it is that it got one message about the channel and another message about the volume. It doesn't care where the messages came from, and the remotes don't know or care if some other remote is sending messages.

I wasn't quite sure what conflict there might have been... I think that was ultimately at the heart of my confusion: understanding the nature of how the object reference variable relates with the actual object. Your use of the TV/remote analogy helped a lot, though (and greatly appreciated that you used it even though you don't like it).
I gotta put this into my own words to test if I really am understanding correctly...
What the "remote" does is to interact with the object without ever actually touching the object, itself, yes? The references do all the work and the object sorta "sits" there.

Well, yes, it definitely varies by language. We're talking about Java here though.

Yeah...I don't know why my friend stated that. It's rather all I go to him for help with...

There are various cases where it's useful. For instance, if parameters are passed to a method or constructor, and you want to copy them to a member variable. The parameter ceases to exist when the method ends, but the member variables lives as long as the object does:
There are various cases where it's useful. For instance, if parameters are passed to a method or constructor, and you want to copy them to a member variable. The parameter ceases to exist when the method ends, but the member variables lives as long as the object does:
public class Person {
private String name;

public Person(String name) {
this.name = name; // now two reference variables point to the same Person object
} // now the "name" parameter no longer exists, but the member variable does
}

Okay, so... The private tag (correct term?) is putting the string name as a variable accessible only within the Person class. Nothing outside can reference or otherwise make use of it.
Assuming I'm correct...
Then the Person object does...? (I still don't yet understand parameters completely...but it's okay, you don't have to explain that. I'll get there.) After the Person object is done, though, that parameter usage of name is done, as well. It has run its course. However, the private variable found in the Person class, itself, still exists because it's a class-defined variable and not a singular instance in the object.

...how'd I do?

Everything else you explained, as I said, pretty much summed things up. Thank you again for your help!
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Michael Miller Jr wrote:Thank you, so much!


You're welcome. Glad I could be of help.

What the "remote" does is to interact with the object without ever actually touching the object, itself, yes?


In the real world, a physical remote and TV, yes. In Java, the notion of the reference "touching" or "not touching" doesn't have any meaning that I can imagine, so I'm not sure what you're trying to say.

The references do all the work and the object sorta "sits" there.


Again, I don't know what you mean by this. I think you may be over-complicating it.

A reference is a value that identifies or locates an object. If you're familiar with C and its pointers, you can imagine a reference as being like a C pointer--that is, being the address of an object. It is not defined as such in the JLS, but it's a reasonable analogy. (And if you are familiar with C/C++, note that Java's reference is much more like C's pointer than C++'s reference.)

So if we have a reference variable X, and we do X.doSometing(), that translates to "in the object pointed to by the reference in variable X, invoke the doSomething() method".

There are various cases where it's useful. For instance, if parameters are passed to a method or constructor, and you want to copy them to a member variable. The parameter ceases to exist when the method ends, but the member variables lives as long as the object does:
There are various cases where it's useful. For instance, if parameters are passed to a method or constructor, and you want to copy them to a member variable. The parameter ceases to exist when the method ends, but the member variables lives as long as the object does:


Okay, so... The private tag (correct term?) is putting the string name as a variable accessible only within the Person class. Nothing outside can reference or otherwise make use of it.


Close. String name declares a variable called "name" of type String. The private access modifier indicates that that variable is accessible only in that class.

Then the Person object does...?


Nothing. That is the execution of this code does not proceed from the declaration of the "name" variable directly to the next line.

In that Person class, we are defining what a Person consists of and what it can do. We've stated that it consists of a "name" variable, and the only other thing we do is state that is has a constructor (to be invoked at instantiation time) that takes a String parameter and assigns its value to our member variable.

When a class's variables, constructors, and methods are accessed and in what order depends on when we call them--it's not a sequential execution from top to bottom of the class.

After the Person object is done, though, that parameter usage of name is done, as well.


No. It's after that particular constructor is done.

It has run its course. However, the private variable found in the Person class, itself, still exists because it's a class-defined variable and not a singular instance in the object.


...how'd I do?


Pretty good. And don't worry if it takes some time for it to all sink in. It's a new way of thinking, and it's natural for it to take some getting used to.
 
Michael Miller Jr
Greenhorn
Posts: 8
Android Chrome Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for that show of understanding and encouragement (both being highly important to me, personally, especially the latter). Fascinating how two "simple" concepts like that make learning all the easier and exciting. Kudos and blessings to you, sir!

In the real world, a physical remote and TV, yes. In Java, the notion of the reference "touching" or "not touching" doesn't have any meaning that I can imagine, so I'm not sure what you're trying to say.

Sorry for the confusion. Just trying to use some mental illustrations to relay my thoughts. An objectReference.method() is, as you said, a pointer to the object and its method, as opposed to utilizing code that interacts more directly with the object (like actually getting up to push the TV's buttons. If that still doesn't clarify things, no worries... You're still explaining things well enough for me at my present skill level/understanding. Heh, moving on.

If you're familiar with C and its pointers, you can imagine a reference as being like a C pointer--that is, being the address of an object.

I'm afraid my last programming language that I had any reasonable "expertise" with was the TI-83 graphing calculator's programming functionality. As I understand it, TI used a modified version of BASIC, so things like loops, breaks, if-thens, whiles, and variables are familiar to me in concept - not including syntax as it appears in Java, though that is working itself out. However, that said, while I'm not familiar at all with any of the C languages, the "address" analogy does make things a bit clearly, though it may not be accurate of Java, as you said. Kind of like how an address to a house points to the house, but is not the house, itself. (We may find an analogy we both like at this rate! LOL)

Everything after that - particularly your explanation about the Person class, is apparently still a bit beyond me. I just only-so-barely got what you were saying. I think I need a few more fundamental instructions... But you've been a great help all the same. God bless!
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Michael Miller Jr wrote:An objectReference.method() is, as you said, a pointer to the object and its method, as opposed to utilizing code that interacts more directly with the object (like actually getting up to push the TV's buttons.

Actually, that's about as direct as code gets in almost any language higher than Assembler. A program has to store objects somewhere and, at least in older languages - not absolutely sure about Java - it's usually in a different part of memory from where the code is actually executed. Therefore, if I have some object called 'fred', the code needs some way of knowing where 'fred' is; hence: references (or pointers).

The main difference between "reference" (String, Object, List...) and "primitive" (char, int, byte...) types, as far as memory alone is concerned, is (a) where they are (or can be) created and (b) how they are handled when calling methods.

If I call a method somewhere in my code, eg:
doSomethingWith(x)
if 'x' is a primitive (say an int with a value of 3), then its value (3) is copied to the doSomethingWith method code.
if 'x' is a reference-type (say a String with a value of "3"), then its reference (ie, its memory address) is copied to the method code. In fact 'x' is a reference to the String, not the String object itself.

This is because the actual objects that references point to can be quite big (suppose, instead of "3", 'x' contained the entire contents of a text file), so there could be a lot of overhead if the entire object had to be copied for each call. Primitives, on the other hand, are very small - long and double are both 64 bits (8 bytes) each; and they're the biggest.

And hopefully that also answers your question about "why would I need two pointers to the same object?" - a method call creates them automatically so that both pieces of code can "see" the same object.

HIH

Winston
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
The main difference between "reference" (String, Object, List...) and "primitive" (char, int, byte...) types, as far as memory alone is concerned, is (a) where they are (or can be) created and (b) how they are handled when calling methods.

If I call a method somewhere in my code, eg:
doSomethingWith(x)
if 'x' is a primitive (say an int with a value of 3), then its value (3) is copied to the doSomethingWith method code.
if 'x' is a reference-type (say a String with a value of "3"), then its reference (ie, its memory address) is copied to the method code. In fact 'x' is a reference to the String, not the String object itself.


Actually, in terms of how the JLS defines things, that's not quite accurate. References are created and live in the same ways and same places as primitives, and if 'x' is a reference type, you're still passing that variable's value to the method. (And that variable's value is a reference.) In terms of human semantics, and especially for simple types that are primarily data holders like String and the Wrapper classes, we think of the object as a "value"--a String with the value "abc", an Integer with the value 123, etc.--but that's not how the term "value" is used in the spec.

Sorry if this confuses things. I think it's important to be as accurate and true to the spec as possible, so that as understanding increases and questions grow more complex, we can refer to the spec more frequently and in greater depth, and be "on the same page" as it is.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:Actually, in terms of how the JLS defines things, that's not quite accurate.

Yeah, I thought I might get pulled up on that; which is why I added the "'x' is a reference" bit.

What I was more interested in doing was explaining a bit of the mechanics of references, as opposed to primitives, to Michael, without getting too bogged down in JLS semantics.

But you're quite right, and I stand corrected.

Winston
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
What I was more interested in doing was explaining a bit of the mechanics of references, as opposed to primitives, to Michael, without getting too bogged down in JLS semantics.


Yeah, I figured as much. It's a fine line to walk--trying to be accurate without getting bogged down in details that hinder understanding of the basic mechanism being discussed. I guess when in doubt, I tend to wobble a bit more toward the "details" side to regain my balance, but there's no hard and fast "right" way to present it.
 
Michael Miller Jr
Greenhorn
Posts: 8
Android Chrome Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Either way, gentlemen, I deeply appreciate the help.
If you can offer any other insight, especially if you have some workable picture analogies, that would be of tremendous help. Thank you, deeply!
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Michael Miller Jr wrote:Either way, gentlemen, I deeply appreciate the help.
If you can offer any other insight, especially if you have some workable picture analogies, that would be of tremendous help. Thank you, deeply!


I don't know what help to offer because I don't know what questions you still have.
 
Michael Miller Jr
Greenhorn
Posts: 8
Android Chrome Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:I don't know what help to offer because I don't know what questions you still have.


Heh, yeah, me, either, at the moment... I guess I just meant in regards to any future posts you might see me put up.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!