arrays and cloning, where is it described?

  • Thread starter Andreas Leitgeb
  • Start date
A

Andreas Leitgeb

It seems to be quite a basic thing, but I found myself
unsure about how it works, and where it is described.
(I didn't find it in JLS nor in the description of
Cloneable or Object.clone() in the javadoc)

According to JLS, arrays are Serializable and Cloneable,
and for multidimensional arrays, the JLS says:
" A clone of a multidimensional array is shallow,
" which is to say that it creates only a single
" new array. Subarrays are shared..
I'm not sure if this should be understood to imply
shallowness also in my case. Why would it have to
explicitly mention multidimensional arrays otherwise?

If I want to deep-copy an array of some Cloneable class,
what would be the best way to do it?

I'd be glad about answers, but even more I'd be glad
about pointers to any of sun's java-documents (jls,
api), where this behaviour or some "deepCopy" method
for arrays of cloneable types is directly described.

Is array's clone/copy altogether the wrong way, and
do I need to create a new array and fill it with
clones of each element, myself?

PS: In my task at hand I do not need to worry about
compiletime/runtime-type: they're the same.
 
S

Sanny

According to JLS, arrays are Serializable and Cloneable,
and for multidimensional arrays, the JLS says:
  " A clone of a multidimensional array is shallow,
  "   which is to say that it creates only a single
  "   new array. Subarrays are shared..
I'm not sure if this should be understood to imply
shallowness also in my case. Why would it have to
explicitly mention multidimensional arrays otherwise?


I tried to copy Single dimensional Array and it works correctly. For
multidimensional Array it do not copy all elements as you think.

int[] array1 = new int[100];
int[] source = new int[100];

array1=source.clone() Works correctly.


int[][] array1 = new int[100][100];
int[][] source = new int[100][100];

array1=source.clone() Does not Copy all elements correctly.

Bye
Sanny

Looking for Experts: http://www.GetClub.com/Experts.php
 
P

Patricia Shanahan

Andreas said:
It seems to be quite a basic thing, but I found myself
unsure about how it works, and where it is described.
(I didn't find it in JLS nor in the description of
Cloneable or Object.clone() in the javadoc)

According to JLS, arrays are Serializable and Cloneable,
and for multidimensional arrays, the JLS says:
" A clone of a multidimensional array is shallow,
" which is to say that it creates only a single
" new array. Subarrays are shared..
I'm not sure if this should be understood to imply
shallowness also in my case. Why would it have to
explicitly mention multidimensional arrays otherwise?

If I want to deep-copy an array of some Cloneable class,
what would be the best way to do it?

I'd be glad about answers, but even more I'd be glad
about pointers to any of sun's java-documents (jls,
api), where this behaviour or some "deepCopy" method
for arrays of cloneable types is directly described.

Is array's clone/copy altogether the wrong way, and
do I need to create a new array and fill it with
clones of each element, myself?

PS: In my task at hand I do not need to worry about
compiletime/runtime-type: they're the same.

The key to understanding this is to accept that Java does not really
have multidimensional arrays. It does have arrays whose elements are of
another array type, and sometimes pretends they are multidimensional
arrays, but not to the extent of making one work consistently as though
it were a single array with multiple dimensions.

Thus "new int[3][4]" is a three element array. Each element is a
reference to a four element array of int.

Cloning it creates a new three element array. Element n of the new array
refers to the same int[4] as element n of the original.

Patricia
 
A

Andreas Leitgeb

Patricia Shanahan said:
The key to understanding this is to accept that Java does not really
have multidimensional arrays....

Sorry for obviously being higly misunderstandable.

My problem isn't about arrays of primitive types.
Not even really "multidimensional" ones.

The docu says: (in other words)
if you clone an "array of array-types" (which are,
btw., also Cloneable) then the referenced arrays
are *not* cloned.
So far so good.

While it almost seems like implied, it doesn't say:
if you clone an array of *any Object-type*,
(which would effectively include array-types)
then only the references, not the objects are
cloned.

Why does it say so specifically about arrays of
arrays, but not about arrays of *any* objects?

Is it, because people might otherwise think that
"arrays of arrays" would be more likely to be deep-
cloned than arrays of other objects?
 
P

Patricia Shanahan

Andreas Leitgeb wrote:
....
Why does it say so specifically about arrays of
arrays, but not about arrays of *any* objects?

Is it, because people might otherwise think that
"arrays of arrays" would be more likely to be deep-
cloned than arrays of other objects?

I suspect so. Java pretends just enough multidimensional array support
to be confusing.

Patricia
 
D

Daniel Pitts

Patricia said:
Andreas Leitgeb wrote:
....

I suspect so. Java pretends just enough multidimensional array support
to be confusing.

Patricia
I think it also makes a mention because array references are special.
Even though they can be assigned to an Object reference, they aren't
really an object. The JLS has to be specific about anything that might
be ambiguous otherwise.
 
M

Mike Schilling

Daniel said:
I think it also makes a mention because array references are
special.
Even though they can be assigned to an Object reference, they aren't
really an object. The JLS has to be specific about anything that
might be ambiguous otherwise.

In what ways are arrays not objects?
 
A

Andreas Leitgeb

But then it is still unspecific about cloning arrays of Objects.
....or I've just still failed to find that mentioned.
In what ways are arrays not objects?

Don't know, if that's what Daniel meant, but arrays are not
accessed through get-/putfield (except for length) or invoke...
opcodes, but through <x>aload/<x>astore opcodes for <x> any
of [abcdfils].

The JLS has some strange wording, such as "can be assigned to
variables of types Object, Cloneable, Serializable", instead
of saying that an array *was* all these.
 
L

Lew

Andreas said:
The JLS has some strange wording, such as "can be assigned to
variables of types Object, Cloneable, Serializable", instead
of saying that an array *was* all these.

Actually, the JLS does say that an array is all these, in ss. 4.10.3
<http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.10.3>
and in 10.7
Every array implements the interfaces Cloneable and java.io.Serializable. and 10.8
The direct superclass of an array type is Object.
Every array type implements the interfaces Cloneable and java.io.Serializable.

The combination of Cloneable and Serializable is somewhat rare outside arrays,
because Cloneable is rare. The combination is implemented by various
java.util classes: ArrayList, Calendar, Date, HashMap, HashSet.

Also in java.sql: Date, Time, Timestamp, by dint of subclassing java.util.Date.

There are a number of additional references in the JLS to the relationship
between Cloneable & Serializable and arrays such as ss. 5.1.6 (Narrowing
Reference Conversion), 5.5 (Casting Conversion), 10 (Arrays), and 5.2
(Assignment Conversion), from whence your paraphrase seems to come.

An array can be assigned only to a variable of a compatible array type,
or to a variable of type Object, Cloneable or java.io.Serializable.

That quote makes sense there because it has to do with assignment conversion.

It is also clearly not instead of saying that an array is "all these" but in
addition to several such mentions.
 
D

Daniel Pitts

Andreas said:
But then it is still unspecific about cloning arrays of Objects.
....or I've just still failed to find that mentioned.
In what ways are arrays not objects?

Don't know, if that's what Daniel meant, but arrays are not
accessed through get-/putfield (except for length) or invoke...
opcodes, but through <x>aload/<x>astore opcodes for <x> any
of [abcdfils].
Actually, "length", is not a field on an array "object". To access the
length of an array, you use a specific opcode.
arraylength
Description

The arrayref must be of type reference and must refer to an array. It is popped from the operand stack. The length of the array it references is determined. That length is pushed onto the operand stack as an int.


The JLS has some strange wording, such as "can be assigned to
variables of types Object, Cloneable, Serializable", instead
of saying that an array *was* all these.
That strange wording is *because* an array is not actually an Object.
Programmers are "tricked" into thinking it is, because it can be
assigned to an Object/Cloneable/Serializable reference.
 
P

Patricia Shanahan

Andreas said:
In what ways are arrays not objects?

Don't know, if that's what Daniel meant, but arrays are not
accessed through get-/putfield (except for length) or invoke...
opcodes, but through <x>aload/<x>astore opcodes for <x> any
of [abcdfils].

That is an implementation detail in compilers that target bytecode, not
a Java language feature.

Patricia
 
M

Mike Schilling

Patricia Shanahan said:
Andreas said:
In what ways are arrays not objects?

Don't know, if that's what Daniel meant, but arrays are not
accessed through get-/putfield (except for length) or invoke...
opcodes, but through <x>aload/<x>astore opcodes for <x> any
of [abcdfils].

That is an implementation detail in compilers that target bytecode, not
a Java language feature.

What Patricia said.

All of the array types (i.e. array of X) are subclasses [1] of Object; to
me, that says that arrays are objects.

1. Descendents, anyway. Do we know for a fact that their immediate
superclass is Object?
 
A

Andreas Leitgeb

Lew said:
There are a number of additional references in the JLS to the relationship
between Cloneable & Serializable and arrays ...

I skimmed over all of these, but still missed any mention of what
clone really does for an array of Objects (or Cloneables, if it
made a difference)

It only says, what it does for an array of arrays, but, as has been
pointed out in this thread, arrays are not normal Objects ... for
some definition of "being" :)

The other question was, if there exists some method for deepCopying
an array of Cloneables.
 
D

Daniel Pitts

Mike said:
Patricia Shanahan said:
Andreas said:
In what ways are arrays not objects?
Don't know, if that's what Daniel meant, but arrays are not
accessed through get-/putfield (except for length) or invoke...
opcodes, but through <x>aload/<x>astore opcodes for <x> any
of [abcdfils].
That is an implementation detail in compilers that target bytecode, not
a Java language feature.

What Patricia said.

All of the array types (i.e. array of X) are subclasses [1] of Object; to
me, that says that arrays are objects.

1. Descendents, anyway. Do we know for a fact that their immediate
superclass is Object?
public class Foo {
public static void main(String[] args) {
System.out.println("Class: " + args.getClass());
System.out.println("Super: " + args.getClass().getSuperclass());
final List<? extends Class<?>> interfaces =
Arrays.asList(args.getClass().getInterfaces());
System.out.println("Interfaces: " + interfaces);
final List<Field> fields =
Arrays.asList(args.getClass().getFields());
System.out.println("Fields:" + fields);
final List<Field> declaredFields =
Arrays.asList(args.getClass().getDeclaredFields());
System.out.println("Declared Fields:" + declaredFields);

}
}


Class: class [Ljava.lang.String;
Super: class java.lang.Object
Interfaces: [interface java.lang.Cloneable, interface java.io.Serializable]
Fields:[]
Declared Fields:[]
 
A

Andreas Leitgeb

Patricia Shanahan said:
Andreas said:
In what ways are arrays not objects?

Don't know, if that's what Daniel meant, but arrays are not
accessed through get-/putfield or invoke... opcodes, but
through <x>aload/<x>astore opcodes for <x> any of [abcdfils].
That is an implementation detail in compilers that target bytecode, not
a Java language feature.

Well there is special syntax for arrays, that cannot be mimicked
by objects... but then, this is also true for enums and collections...
Nah! let's stop this hairsplitting :)
 
M

Mike Schilling

Daniel Pitts said:
Mike said:
Patricia Shanahan said:
Andreas Leitgeb wrote:
...
In what ways are arrays not objects?
Don't know, if that's what Daniel meant, but arrays are not
accessed through get-/putfield (except for length) or invoke...
opcodes, but through <x>aload/<x>astore opcodes for <x> any
of [abcdfils].
That is an implementation detail in compilers that target bytecode, not
a Java language feature.

What Patricia said.

All of the array types (i.e. array of X) are subclasses [1] of Object; to
me, that says that arrays are objects.

1. Descendents, anyway. Do we know for a fact that their immediate
superclass is Object?
public class Foo {
public static void main(String[] args) {
System.out.println("Class: " + args.getClass());
System.out.println("Super: " + args.getClass().getSuperclass());
final List<? extends Class<?>> interfaces =
Arrays.asList(args.getClass().getInterfaces());
System.out.println("Interfaces: " + interfaces);
final List<Field> fields =
Arrays.asList(args.getClass().getFields());
System.out.println("Fields:" + fields);
final List<Field> declaredFields =
Arrays.asList(args.getClass().getDeclaredFields());
System.out.println("Declared Fields:" + declaredFields);

}
}


Class: class [Ljava.lang.String;
Super: class java.lang.Object
Interfaces: [interface java.lang.Cloneable, interface
java.io.Serializable]
Fields:[]
Declared Fields:[]

Yes, I know that the superclass is Object *now*, but I don't know whether
this is guaranteed.
 
P

Patricia Shanahan

L

Lew

Andreas said:
I skimmed over all of these, but still missed any mention of what
clone really does for an array of Objects (or Cloneables, if it
made a difference)

The references were only by way of showing that the JLS does say "that an
array *was* all these", not that it explains what clone() does.

What clone() does is, strangely, documented in the Javadocs for clone(),
specifically,
To achieve this independence, it may be necessary to modify one or more fields
of the object returned by super.clone before returning it.
Typically, this means copying any mutable objects that comprise the internal
"deep structure" of the object being cloned and replacing the references to
these objects with references to the copies.

The details of what it does to an array are covered in one of the JLS links I
mentioned:
public T[] clone() {
try {
return (T[])super.clone(); // unchecked warning
} catch (CloneNotSupportedException e) {
throw new InternalError(e.getMessage());
}

Taken together, these two sources answer your question.
 
L

Lew

Patricia said:

/op. cit./, /supra/.
"The direct superclass of an array type is Object."

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getSuperclass()


"If this object represents an array class then the Class object
representing the Object class is returned."

If we keep repeating the information enough, eventually it will get through.
It certainly is mentioned in enough places in the JLS:

4.10.3 Subtyping among Array Types
The following rules define the direct subtype relation among array types:

* If S and T are both reference types, then S[] >1 T[] iff S >1 T.
* Object >1 Object[]
* Cloneable >1 Object[]
* java.io.Serializable >1 Object[]
* If p is a primitive type, then:
o Object >1 p[]
o Cloneable >1 p[]
o java.io.Serializable >1 p[]

/op. cit./, /supra/.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top