Also see: http://www.pipeline.com/~hbaker1/ObjectIdentity.html for a very good discussion of these issues
Moved and condensed from JavaDoesntPassByValue. -- PhilGoodwin
PhilGoodwin: Java doesn't support ValueSemantics for objects at all. ValueObjects are made immutable in order to force their users to implement ValueSemantics by hand and the only way to get ValueSemantics for a mutable object is to make your own copy of it by hand. It's kind of a pain if you're used to C++ but it does save memory on the stack and it makes garbage collection and security much easier.
DaveHarris: I think that you're hung up on the idea of pointers and the implementation detail that values are stored somewhere in RAM. If "foo" is a variable with the value of one then it is attached to one. It is not, itself one, it is merely attached to one. We can change foo without changing one. One is not a 32-bit (or whatever) slot carved out in memory somewhere. One is an immutable thing that can be stored in such a slot.
So "foo" behaves exactly like a normal reference type (in java). If we pretend that java is typeless for a moment then:
foo = 1;and
foo = new Integer(1);differ only in the that latter has an identity separate from its value. We could eliminate even that through the use of a factory method.
I think this stuff is easier to see in Smalltalk where 1 is a full object which seamlessly interacts with other objects. The implementation may give it a special representation, but that's just an efficiency hack which doesn't affect the semantics.
PhilGoodwin: I agree that variables are holders for values (and can change), but they are not the values themselves (which cannot change). But I want to go further and say that references are a kind of value and that the state of an object is another kind of value.
DaveHarris: A reference both is a value and has a value. It's two values. The value it is is its identity. The value it has is the value it is attached to. For a variable, the attachment can be changed. The notion of an attachment is important to understanding this, because the attachments are the only things which truly change.
PhilGoodwin: I prefer to keep the concepts of reference and variable separate because that gives me a model that I can use not only for java programming but for C, C++ or assembly language.
DaveHarris: Notice I have also distinguished them. I use my model for all those languages and more.
PhilGoodwin: It also helps me because I think that an object is like a variable because it holds a value (its state) which can change. My point in JavaDoesntPassByValue is that java cannot store the value of an object as a parameter, or any other sort of variable for that matter, and therefore cannot pass objects by value.
DaveHarris: I agree that "The state of an object is another kind of value". The representation of an object can contain instance variables, the attachments of the instance variables can change and that is what happens when the object "changes state". But an object is not just "like a variable" in my mind. An object isn't a variable, an object contains variables. The value that it is, doesn't change. The value that it has, does. When you say, "java cannot store the value of an object", you fail to specify which of the two values it does not store.
PhilGoodwin: Does that mean to you that a reference and an object are the same thing? (at least in java)
DaveHarris: No. An object can contain references. That doesn't mean they are the same thing.
PhilGoodwin: It is interesting to me that java lets you store primitive values, including references, as variables, but won't let you get a reference to them.
DaveHarris: Java does let you store references to primitive values. That is what an int variable is: a named reference to an integer value.
PhilGoodwin: While on the other hand it won't let you store objects in variables, but will allow you to get a reference to them. I think that this causes people to mistakenly think that variables and references are the same thing. They are not. A value and it's identity are one and the same.
DaveHarris: But I think that they are: A variable is a reference whose attachment can change.
PhilGoodwin: You cannot have a value with more than one identity and you cannot change the value associated with an identity. If you want to make a reference to an object act like the value of the object. You must prevent the value associated with the reference from changing by making the object immutable and you must ensure that only one reference exists for the value (which you allude to in your reference to factory methods above.) After that the reference still isn't the value it refers to, but it might as well be.
DaveHarris: That is what happens with ints. Ints are lacking both mutability and identity (or at least, their identity is well hidden). Objects may or may not be mutable, but always have an extra value, their identity, which is not hidden well.
(It sometimes helps to think of identity not so much as the object's address, but as an extra field associated with the object, which can be used as the key to an IndexedCollection?. This key is the value which distinguishes one Integer from another, and is what ints hide.)
PhilGoodwin: I don't think that I can agree with that. The identity of an object is almost certainly implemented, directly or indirectly, as it's address at the lowest level and it helps me to think of it that way. A reference is a type of variable that can hold an address. A variable is a symbolic name for a range of addresses. For instance if "foo" is a local "int" variable then it could literally mean the same thing as "four consecutive bytes starting eight bytes past the start of the current stack frame".
DaveHarris: To think of it as 4 bytes of RAM may help with C++ or assembler, but it doesn't generalize well. In Python, a variable is an (string) index into a dictionary. URLs are also references. The process of converting an URL into the value (page) it's attached to is quite complex (involving web servers, file systems etc).
PhilGoodwin: It seems to work for me: it's still a name for a place in the program in which I can store values. As it happens, it's also a value that I can store as a reference - you can't do that with ordinary references. So for me, it's sort of a combination of two atomic things.