How to implement generics with clone()?

M

Matteo

I need to use clone() on generics but I don't know how to do.
If I write, for example,

Vector<String> v1 = new Vector<String>();
Vector<String> v2 = new Vector<String>();
v1.add("a");
v2 = v1.clone();

it gives me the error

xyz: incompatible types
found : java.lang.Object
required: java.util.Vector<java.lang.String>
v2 = v1.clone();
^

if I cast to generics doing

Vector<String> v1 = new Vector<String>();
Vector<String> v2 = new Vector<String>();
v1.add("a");
v2 = (Vector<String>)v1.clone();

it gives me the warning:
Util.java:252: warning: [unchecked] unchecked cast
found : java.lang.Object
required: java.util.Vector<java.lang.String>
v2 = (Vector<String>)v1.clone();
^
1 warning

Well, I can understand this because clone() returns an Object.
But how I can use clone without warnings??

Thank you vey much,
Matteo
 
A

Alex Hunsley

Matteo said:
I need to use clone() on generics but I don't know how to do.
If I write, for example,
[snip]

clone() is broken and horrible. I'd avoid it if I were you.

alex
 
M

Mike Schilling

Matteo said:
I need to use clone() on generics but I don't know how to do.
If I write, for example,

Vector<String> v1 = new Vector<String>();
Vector<String> v2 = new Vector<String>();
v1.add("a");
v2 = v1.clone();

it gives me the error

xyz: incompatible types
found : java.lang.Object
required: java.util.Vector<java.lang.String>
v2 = v1.clone();
^

if I cast to generics doing

Vector<String> v1 = new Vector<String>();
Vector<String> v2 = new Vector<String>();
v1.add("a");
v2 = (Vector<String>)v1.clone();

it gives me the warning:
Util.java:252: warning: [unchecked] unchecked cast
found : java.lang.Object
required: java.util.Vector<java.lang.String>
v2 = (Vector<String>)v1.clone();
^
1 warning

Well, I can understand this because clone() returns an Object.
But how I can use clone without warnings??

I think that the answer is that you can't, and that this is a special case
of a more general rule:

You can't convert an unqualified type (e.g. Object, Vector) to a
qualified type (e.g. Vector<String>) without warnings.

That's because of type erasure: there is no runtime check that the object is
actually a Vector<String> as (opposed to a simple Vector or Vector<File>) so
the cast is always unsafe and will always result in a warning.
 
M

Matteo

Alex Hunsley said:
Matteo said:
I need to use clone() on generics but I don't know how to do.
If I write, for example,
[snip]

clone() is broken and horrible. I'd avoid it if I were you.

alex

Ok, I'll made a copy by hand .... Or can I use another function?

thx!
 
A

Alex Hunsley

Matteo said:
Alex Hunsley said:
Matteo said:
I need to use clone() on generics but I don't know how to do.
If I write, for example,

[snip]

clone() is broken and horrible. I'd avoid it if I were you.

alex


Ok, I'll made a copy by hand .... Or can I use another function?

thx!

One of the nicer places to put your copy function is as a constructor
(of the class you want to copy) that takes an instance of the class and
copies it.

read here about copy constructors:
http://www.javapractices.com/Topic12.cjp

there's something about clone() here and why it's a bit evil:
http://www.javapractices.com/Topic71.cjp

HTH,
alex
 
C

Chris Smith

Alex said:
One of the nicer places to put your copy function is as a constructor
(of the class you want to copy) that takes an instance of the class and
copies it.

read here about copy constructors:
http://www.javapractices.com/Topic12.cjp

there's something about clone() here and why it's a bit evil:
http://www.javapractices.com/Topic71.cjp

If only it were that simple. The clone() method is certainly clumsy and
difficult, but it solves problems that are not solved by copy
constructors. Copy constructors are broken when inheritance is used,
since the object that you get as a result of the "copy" will be a
different class from the one you attempted to copy. Clone is the right
answer, even if it's a bit confused.

Unfortunately, there apparently isn't a way to properly implement and
use clone() on a generic class without getting unchecked cast warnings.
You can either deal with the warnings, or settle for a less than optimal
means of copying objects. Though copy constructors are broken in the
general case, they may work for you if you know that inheritance isn't
needed.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
A

Alex Hunsley

Chris said:
If only it were that simple. The clone() method is certainly clumsy and
difficult, but it solves problems that are not solved by copy
constructors.

And it also introduces problems that would be handled by copy
constructors. clone() is horrible, horrible, horrible.
Also, copy constructors do offer possibilities that clone() doesn't,
such as interface based copy constructors.
Copy constructors are broken when inheritance is used,
since the object that you get as a result of the "copy" will be a
different class from the one you attempted to copy. Clone is the right
answer, even if it's a bit confused.

Unfortunately, there apparently isn't a way to properly implement and
use clone() on a generic class without getting unchecked cast warnings.
You can either deal with the warnings, or settle for a less than optimal
means of copying objects. Though copy constructors are broken in the
general case, they may work for you if you know that inheritance isn't
needed.

Clone is just too broken, and has too many caveats, for my liking.
For example: the docs regarding clone (see object.clone()) are too weak
in their demands/spec.
The whole cloneable interface design/feature is a great example of
misuse of the interface paradigm. Also, clone() is effectively a
constructor masquerading as something else: for example, you can get the
same problems when calling non-final (or non-private) methods from
clone() as you when when doing likewise from a constructor.
And what about final fields? clone breaks the ability to use final
fields in a normal way (when they refer to mutables).

This probably comes down to differing likes; I just think that clone
should be avoided if at all possible as it can be such a nightmare.
 
C

Chris Smith

Alex said:
Also, copy constructors do offer possibilities that clone() doesn't,
such as interface based copy constructors.

Can you explain what you mean? I haven't heard that phrase before, and
neither has Google.
Clone is just too broken, and has too many caveats, for my liking.

You're right; there are a lot of things done wrong with clone(). That
doesn't make clone() a bad thing to use; it makes clone() a poorly
implemented good idea. The Cloneable interface should certainly have
declared a public clone() method that doesn't throw
CloneNotSupportedException. Furthermore, generics should be implemented
properly to avoid arbitrary restrictions on type-casting to generic
types (and because of the braindead nature of this limitation, I'd
encourage people to respond by simply ignoring "unchecked cast"
warnings).

None of that makes clone() a bad idea, though. It means it could have
been better. It doesn't come close to the problem with copy
constructors when you've got inheritance; there's simply no reliable way
to ensure that an object with subclasses can be copied without clone().
The best you can do is write code with reflection to try to find a
signature in the subclass that looks like a C++ copy constructor, but in
Java (unlike C++) there's no guarantee that the C++ copy constructor
convention is being followed.
This probably comes down to differing likes;

Perhaps. It may also come down to differing use of the remainder of the
language. Some developers make differing use of polymorphism than
others, and if you never copy objects from reference types that have
subclasses, then copy constructors would work fine.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

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,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top