
Signature
Eric Sosman
esosman@acm-dot-org.invalid
>> What is the difference between doing this with two string arrays:
>>
[quoted text clipped - 63 lines]
> C or C++ doesn't affect the pointed-to thing; copying a
> reference in Java acts similarly.
I don't know C or C++, but I've heard of pointers and read comments in
places about Java not having pointers. I'm self taught (other than a VAX
11/780 Assembler class in the 1980s), so I find there's a lot of times that
I know some advanced concepts and miss things that I should know.
If I understand all this correctly, then if I want to duplicate a String[]
function, I need to do something like this:
String[] oldCopy = { "Duke", "rulez!" };
String[] newCopy = new String[oldCopy.length];
int i;
for (i = 1; i < oldCopy.length; i++) {
newCopy[i] = oldCopy[i].clone();
}
Is that right? Since I can create a new array that will still reference the
old strings, it seems that the only way to create a complete copy as it is,
as an independent object to save the exact state of oldCopy is to clone
each String individually.
Hal
Eric Sosman - 15 Aug 2006 19:18 GMT
Hal Vaughan wrote On 08/15/06 12:55,:
> [...]
> If I understand all this correctly, then if I want to duplicate a String[]
[quoted text clipped - 4 lines]
> int i;
> for (i = 1; i < oldCopy.length; i++) {
ITYM 0 instead of 1 here.
> newCopy[i] = oldCopy[i].clone();
This won't work for at least three reasons, one of them
fixable and the other two inescapable (to the best of my
knowledge).
The fixable problem is that clone() returns an Object
reference but you need a String reference, so the statement
won't compile. You could add a (String) cast to solve that
problem; the compiler would insert code to do a run-time check
that the Object is in truth a String, and then either allow
the assignment or throw ClassCastException.
The first inescapable problem is that the clone() method
of String is protected, meaning that it's accessible only
from within the String class itself, from within other classes
of the java.lang package, or from subclasses of String. Since
your code is not part of String nor part of java.lang, and
since String is final and can have no subclasses, your code
cannot call String's clone() method.
The second inescapable problem is that even if you somehow
managed to call clone() on a String, you would find that the
String class does not implement the Cloneable interface. The
clone() method (whose implementation String inherits from
Object) will just throw a CloneNotSupportedException and
snicker at you behind your back.
The upshot: You can't clone a String -- and String is not
unique in being non-cloneable, either.
> [...] Since I can create a new array that will still reference the
> old strings, it seems that the only way to create a complete copy as it is,
> as an independent object to save the exact state of oldCopy is to clone
> each String individually.
You could *copy* (not *clone*) the String objects by using
String's copy constructor, or by a few other routes. But it's
a dumb thing to do: Why do you think you need all those copies?
Keep in mind that a String is immutable; once it's been created
its content cannot change. If the String eventually expires,
it will have its original value right up to the instant when
the garbage collector swings its scythe. (Well, somebody once
posted a horrible hack that showed how a String could in fact
be changed -- but if *that* sort of mischief is afoot in your
JVM, you might as well throw in the towel.)
Do you clone yourself when you tell someone your name? Do
you give away cloned copies, or do you let the other people
access the one and only You through a reference?

Signature
Eric.Sosman@sun.com
Hal Vaughan - 15 Aug 2006 19:40 GMT
> Hal Vaughan wrote On 08/15/06 12:55,:
>> [...]
[quoted text clipped - 54 lines]
> be changed -- but if *that* sort of mischief is afoot in your
> JVM, you might as well throw in the towel.)
I'm using a "restore to last saved" option in the menu so if someone makes
mistakes, they can revert to the last saved data. I need to store several
String[] structures as they are when the data is saved so they can be used
later if needed.
Hal
Eric Sosman - 15 Aug 2006 20:38 GMT
Hal Vaughan wrote On 08/15/06 14:40,:
>> You could *copy* (not *clone*) the String objects by using
>>String's copy constructor, or by a few other routes. But it's
[quoted text clipped - 4 lines]
> String[] structures as they are when the data is saved so they can be used
> later if needed.
You may need a copy of the String[], which is an array of
references to String objects, but there's no need to make copies
of the String objects those references point to.
Here's the original array, before anybody edits anything:
oldarray[0] -> "Duke"
oldarray[1] -> "rulez!"
Now make a new copy of the array and the references it contains,
which point to the original String objects:
oldarray[0] -> "Duke" <- newarray[0]
oldarray[1] -> "rulez!" <- newarray[1]
Now edit the new array, changing one of its references to point
to a different String:
oldarray[0] -> "Duke" newarray[0] -> "Elvis"
oldarray[1] -> "rulez!" <- newarray[1]
There is no need for extra copies of "rulez!" or of "Duke".
All the String objects are still alive, still referred to,
still hanging on to their immutable content. If you want
to commit the edit, keep newarray and let oldarray drop on
the floor. If you want to revert, keep oldarray and abandon
newarray to the garbage collector.
I think the distinction between an object reference and
an object instance is not yet quite clear to you. When the
light eventually dawns, things will make sense quite suddenly.
Objects are telephones; references are telephone numbers.
If you want to get calls from a hundred people, give out a
hundred copies of your telephone number -- a hundred copies
of the reference value -- but don't burden yourself by trying
to carry a hundred phones on your belt.

Signature
Eric.Sosman@sun.com
Patricia Shanahan - 15 Aug 2006 19:43 GMT
....
> I don't know C or C++, but I've heard of pointers and read comments in
> places about Java not having pointers. I'm self taught (other than a VAX
> 11/780 Assembler class in the 1980s), so I find there's a lot of times that
> I know some advanced concepts and miss things that I should know.
Java does have pointers, though they are called "references". It lacks a
lot of dangerous baggage that C added to the concept of "pointer", such
as pointer arithmetic, conversion between pointer and integer types, and
unchecked pointer conversions. Java forces its references to either be
null or point to an object of appropriate class.
Because a lot of programmers learned about pointers in connection with
C, some writers about Java try to avoid the word, on the theory that
anyone learning Java would be too dumb to understand that Java pointers
just point to objects, and don't do anything else.
> If I understand all this correctly, then if I want to duplicate a String[]
> function, I need to do something like this:
[quoted text clipped - 10 lines]
> as an independent object to save the exact state of oldCopy is to clone
> each String individually.
String[] oldCopy = { "Duke", "rulez!" };
String[] newCopy = new String[oldCopy.length];
int i;
for (i = 1; i < oldCopy.length; i++) {
newCopy[i] = new String(oldCopy[i]);
}
but there are VERY few situations in which you need anything like that.
Why do you want to avoid sharing String objects?
Patricia
Hal Vaughan - 15 Aug 2006 20:00 GMT
> ....
>> I don't know C or C++, but I've heard of pointers and read comments in
[quoted text clipped - 40 lines]
>
> Patricia
I want a backup of the object at a particular time so the user can revert to
the last saved state if desired, so I need to be able to copy the object
and make sure the copy doesn't have the new changes made after the copy is
done.
Hal
Patricia Shanahan - 15 Aug 2006 21:20 GMT
...
>> Why do you want to avoid sharing String objects?
>>
[quoted text clipped - 4 lines]
> and make sure the copy doesn't have the new changes made after the copy is
> done.
You need to make sure the object your backup references does not have
any changes made after the backup was done. Copying is only a means to
that end.
You can divide objects, for this purpose, into two categories, mutable
and immutable.
An immutable object has no methods that change its own state. For an
immutable object, such as a String, you only need to copy the reference.
String is not Cloneable because you don't need to copy it for this sort
of situation.
The state of a mutable object can change, so to be sure of getting back
to an earlier state you need a copy of the object, not just a reference.
Patricia