How to implement generics with clone()?

Discussion in 'Java' started by Matteo, Oct 18, 2004.

  1. Matteo

    Matteo Guest

    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
     
    Matteo, Oct 18, 2004
    #1
    1. Advertisements

  2. Matteo

    Alex Hunsley Guest

    [snip]

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

    alex
     
    Alex Hunsley, Oct 18, 2004
    #2
    1. Advertisements

  3. 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.
     
    Mike Schilling, Oct 18, 2004
    #3
  4. Matteo

    Matteo Guest

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

    thx!
     
    Matteo, Oct 19, 2004
    #4
  5. Matteo

    Alex Hunsley Guest

    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
     
    Alex Hunsley, Oct 19, 2004
    #5
  6. Matteo

    Chris Smith Guest

    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
     
    Chris Smith, Oct 19, 2004
    #6
  7. Matteo

    Alex Hunsley Guest

    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.
    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.
     
    Alex Hunsley, Oct 19, 2004
    #7
  8. Matteo

    Chris Smith Guest

    Can you explain what you mean? I haven't heard that phrase before, and
    neither has Google.
    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.
    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
     
    Chris Smith, Oct 20, 2004
    #8
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.