Baffling compiler warning using clone()

W

Wes Harrison

I get a compiler warning:

ClassA.java:195: warning: [unchecked] unchecked cast
found : java.lang.Object
required: java.util.ArrayList<java.lang.Integer>

in the following code:

ArrayList<Integer> myList = new ArrayList<Integer>;
ArrayList<Integer> clone = (ArrayList<Integer>)myList.clone();

that I would like to get rid of but I can't see why it is a warning at all.
Can anyone explain why this is a warning and the way to code around it?

Thanks,

Wes
 
T

Timo Stamm

Wes said:
I get a compiler warning:

ClassA.java:195: warning: [unchecked] unchecked cast
found : java.lang.Object
required: java.util.ArrayList<java.lang.Integer>

in the following code:

ArrayList<Integer> myList = new ArrayList<Integer>;
ArrayList<Integer> clone = (ArrayList<Integer>)myList.clone();

that I would like to get rid of but I can't see why it is a warning at all.

Short answer: Because of Generics.

Can anyone explain why this is a warning and the way to code around it?

@SuppressWarnings("unchecked")
ArrayList<Integer> clone = (ArrayList<Integer>)myList.clone();

or

ArrayList clone = (ArrayList)myList.clone();

or

ArrayList<Integer> clone = new ArrayList<Integer>(myList);


Timo
 
C

Chris Smith

Luc The Perverse said:
Somehow, this one "feels" like the right one.

There is no right one. The problem with this one is that it's not
general enough. In a class hierarchy where there is meaning attached to
the subclass of which an object is an instance, but the information is
not statically known, copying an object by using "new" and a constructor
that does the copy is tragically broken. With ArrayList, it's probably
okay.

Of course, the other options aren't all that great, either. But that's
what we're left with due to the runtime type erasure of generics in
Java. It's a choice between bad code or compiler warnings.
 
T

Thomas Hawtin

Chris said:
Of course, the other options aren't all that great, either. But that's
what we're left with due to the runtime type erasure of generics in
Java. It's a choice between bad code or compiler warnings.

It is not really to do with erasure. ArrayList could have used covariant
return types on clone (or a similar method). ArrayList can be subclassed
to provide such a method.

If it was good code, it would probably be referring to List rather than
ArrayList anyway.

Tom Hawtin
 
C

Chris Smith

Thomas Hawtin said:
It is not really to do with erasure. ArrayList could have used covariant
return types on clone (or a similar method). ArrayList can be subclassed
to provide such a method.

Well, yes it's to do with erasure. It's true that ArrayList could have
defined a covariant return type for clone(). That would simply have
moved the warning. That is:

public class TestCovar<T>
{
@Override
public TestCovar<T> clone()
{
try
{
return (TestCovar<T>) super.clone();
}
catch (CloneNotSupportedException e) { ... }
}
}

gives the same warning when casting from Object to TestCovar<T> as did
the cast *outside* of the method with a covariant return type.

Hence, the warning message is not avoidable.
If it was good code, it would probably be referring to List rather than
ArrayList anyway.

How is that relevant. Do you know of a way to clone a general List<T>
that avoids this problem?
 
D

Daniel Dyer

Well, yes it's to do with erasure. It's true that ArrayList could have
defined a covariant return type for clone(). That would simply have
moved the warning. That is:

public class TestCovar<T>
{
@Override
public TestCovar<T> clone()
{
try
{
return (TestCovar<T>) super.clone();
}
catch (CloneNotSupportedException e) { ... }
}
}

gives the same warning when casting from Object to TestCovar<T> as did
the cast *outside* of the method with a covariant return type.

Hence, the warning message is not avoidable.

It still would have been preferable for Sun to make the change in 5.0. As
far as I can see, it wouldn't have broken anything and at least would have
dealt with the issue in one central place.
How is that relevant. Do you know of a way to clone a general List<T>
that avoids this problem?

Of course, there are two problems there. Firstly, List doesn't extend
Cloneable. And secondly, my pet hate, even if it did, Cloneable does not
declare the clone method. Perhaps the Cloneable interface should be
renamed 'MaybeCloneableMaybeNot'?

Dan.
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top