Clone method in doc fails

In

http://java.sun.com/docs/books/jls/third_edition/html/arrays.html#10.1

I find this example:

class Test {

public static void main(String[] args) throws Throwable {

int ia[][] = { { 1 , 2}, null };

int ja[][] = ia.clone();

System.out.print((ia == ja) + " ");

System.out.println(ia[0] == ja[0] && ia[1] == ja[1]);

}

}

Yet when I cut and paste and compile, it doesn't compile. I get:

Test.java:4: incompatible types

found: java.lang.Object

required: int[]

int ia2[] = ia1.clone();

?

1 error

I hate it when the examples in the docs don't work. Anyone have any suggestions?

TIA for any help.

[722 byte] By [Trainers_Frienda] at [2007-11-27 5:19:21]
# 1
Clone returns an object. You have to cast it back into an array.int ia2 = (int[]) ia1.clone();
ktm5124a at 2007-7-12 10:42:41 > top of Java-index,Java Essentials,New To Java...
# 2

It compiles OK when I try it. As 10.7 says "The public method clone, which overrides the method of the same name in class Object and throws no checked exceptions. The return type of the clone method of an array type T[] is T[]."

But as Sun's Tutorial explains (http://java.sun.com/docs/books/tutorial/java/IandI/override.html) "An overriding method can also return a subtype of the type returned by the overridden method. This is called a covariant return type." Covariant return types have been available since 1.5.

pbrockway2a at 2007-7-12 10:42:41 > top of Java-index,Java Essentials,New To Java...
# 3
Well, that worked. But why didn't the doc have the cast in the example?
Trainers_Frienda at 2007-7-12 10:42:41 > top of Java-index,Java Essentials,New To Java...
# 4

Reply:

It compiles OK when I try it.

-- hmmm. Wonder what's the difference; tried with both 1.4 under

z/OS and 1.6 under WinXP

As 10.7 says "The public method clone, which overrides the method of the same name in class Object and throws no checked exceptions. The return type of the clone method of an array type T[] is T[]."

-- Well, I don't understand that (the first sentence is not correct English,

by any stretch of the imagination). And I don't understand the relevance

of that quote to the original post. Could you explain the significance of

those sentences to real code?

But as Sun's Tutorial explains (http://java.sun.com/docs/books/tutorial/java/IandI/override.html) "An overriding method can also return a subtype of the type returned by the overridden method. This is called a covariant return type." Covariant return types have been available since 1.5.

-- I'm sorry, but I don't get the point of all that.

Trainers_Frienda at 2007-7-12 10:42:41 > top of Java-index,Java Essentials,New To Java...
# 5

> Wonder what's the difference; tried with both 1.4 under

> z/OS and 1.6 under WinXP

What happened when you tried that?

By "it compiles OK", I meant that I saw the rather unexceptional:pbrockway@linuxdeskd6off:~/Desktop/jdk$ cat Test.java

class Test {

public static void main(String[] args) throws Throwable {

int ia[][] = { { 1 , 2}, null };

int ja[][] = ia.clone();

System.out.print((ia == ja) + " ");

System.out.println(ia[0] == ja[0] && ia[1] == ja[1]);

}

}pbrockway@linuxdeskd6off:~/Desktop/jdk$ javac -version

javac 1.6.0

pbrockway@linuxdeskd6off:~/Desktop/jdk$ javac -cp . Test.java

pbrockway@linuxdeskd6off:~/Desktop/jdk$and with WindowsXP SP2, I just tried and seeC:\jdc>javac -version

javac 1.6.0

C:\jdc>javac -cp . Test.java

C:\jdc>> > As 10.7 says "The public method clone, which overrides the

> > method of the same name in class Object and throws no checked

> > exceptions. The return type of the clone method of an array type T[]

> > is T[]."

> Well, I don't understand that (the first sentence is not correct English,

> by any stretch of the imagination). And I don't understand the relevance

> of that quote to the original post.

Well the English is as good as it gets in these days where we're increasingly ruled by the bullet. In full it says ... no, but of course you've looked that up!

The OP (or at least his compiler message) was talking about the declared type of ja and the return type of ia.clone(). Specifically the type T referred to by the JLS is the type int in the OP's (and the JLS's) code.

> Could you explain the significance of those sentences to real code?

The significance lies in the fact that both ja and ia.clone() are of type int[]. And what it signifies is that the code compiles, as expected, without a cast and without an error.

> > But as Sun's Tutorial explains (http://java.sun.com/docs/books/tutorial/java/IandI/override.html)

> > "An overriding method can also return a subtype of the type returned by the overridden method.

> > This is called a covariant return type." Covariant return types have been available since 1.5.

> -- I'm sorry, but I don't get the point of all that.

I was just wondering if what the OP posted resulted from the fact that he was using a version of java that required ia.clone() to override Object's clone method in the narrow sense of returning exactly the same type (as was required pre 1.5).

pbrockway2a at 2007-7-12 10:42:41 > top of Java-index,Java Essentials,New To Java...
# 6

Sorry - I've just realised that I was replying to you (the OP) in the previous post!

OK - you've said what you saw. Did you get that error message with *both* 1.4 and 1.6? As you can see from what I posted, it's easy enough to check with "javac -version" that you are using the compiler you think you are using.

As far as I know the JLS doesn't mention the cast because the cast is not, in fact, necessary.

pbrockway2a at 2007-7-12 10:42:41 > top of Java-index,Java Essentials,New To Java...
# 7

OP here.

On my z/OS 1.7, a java -version returns:

java version "1.4.2"

Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2)

Classic VM (build 1.4.2, J2RE 1.4.2 IBM z/OS Persistent Reusable VM build cm142ifx-20060209 (SR4-1) (JIT enabled: jitc))

If I compile the example _exactly_ as it shows in the doc:

class Test {

public static void main(String[] args) {

int ia1[] = { 1, 2 };

int ia2[] = ia1.clone();

System.out.print((ia1 == ia2) + " ");

ia1[1]++;

System.out.println(ia2[1]);

}

}

I get:

Test.java:4: incompatible types

found: java.lang.Object

required: int[]

int ia2[] = ia1.clone();

?

1 error

Hmmm. I notice your example doesn't quite match the example in the doc:

* you have a Throws clause on your main header

* you declare a two dimensional array instead of a one dimensional one

* your println statement is different

* you aren't incrementing the first element

when I compile your version, I find:

Test.java:4: incompatible types

found: java.lang.Object

required: int[][]

int ja[][] = ia.clone();

?

1 error

So, I'm baffled again. [BTW, when I simply add the cast as one poster

suggested, it compiles clean and runs as the doc says it should.]

So, on my WinXP system, I have:

java -version

java version "1.6.0_01"

(how come you said "javac -version" instead of "java -version"?

Anyway, if I compile the original code, as found in the doc, I get:

Test.java:4: Incompatible types

found:: java.lang.Object

required: int[]

int ia2[] = ia1.clone();

?

When I compile the code with the cast added, it compiles clean

and runs as expected.

When I compile your code, I get:

Test.java:4: incompatible types

found: java.lang.Object

required: int[][]

int ja[][] = ia.clone();

?

1 error

So I don't see how you got a clean compile; and I'm still back to

my original dilema: the example in the doc does not seem to

compile as is.

Trainers_Frienda at 2007-7-12 10:42:41 > top of Java-index,Java Essentials,New To Java...
# 8

Before Java 5 the language had no covariant return types, so clone() had to return Object. This means that the statementint ia2[] = ia1.clone();

was not legal. You needed to cast the return value like this:int ia2[] = (int[]) ia1.clone();

Since Java 5 the language has contravariant return types and the cast is not needed. The tutorial requires Java 6.

> (how come you said "javac -version" instead of "java -version"?

You need a compiler from Java 5 or later to compile the example. Did "javac -version" give you an error? Then you have several runtime environments on your computer and the compiler javac that you used is from a version before Java 5. Make sure that the Java 6 SDK is mentioned before other versions in the PATH environment variable.

In all versions of the SDK you can verify the version of javac with the command "javac -J-version".

jsalonena at 2007-7-12 10:42:41 > top of Java-index,Java Essentials,New To Java...
# 9
Thanks for that cogent and coherent explanation. It was just what I needed.
Trainers_Frienda at 2007-7-12 10:42:41 > top of Java-index,Java Essentials,New To Java...
# 10
> Since Java 5 the language has contravariant return types hmm there's an error here: the return types are covariant, not contravariant. http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
jsalonena at 2007-7-12 10:42:41 > top of Java-index,Java Essentials,New To Java...