1

I have a class that stores certain events and gives out clones, but Eclipse (my IDE) gives me unchecked clone warnings:

import java.util.*;
import java.awt.event.*;

public PlayerEvents {

    private final ArrayList<KeyEvent> keyevents;
    private final ArrayList<MouseEvent> mouseevents;

    @SuppressWarnings("unchecked") // I have to do this to keep the IDE quiet
    public PlayerEvents(ArrayList<KeyEvent> keyevents, ArrayList<MouseEvent> mouseevents) {
        this.keyevents = (ArrayList<KeyEvent>) keyevents.clone(); // Type safety: Unchecked cast from Object to ArrayList<KeyEvent>
        this.mouseevents = (ArrayList<MouseEvent>) mouseevents.clone(); // Type safety: Unchecked cast from Object to ArrayList<KeyEvent>
    }

    // More code...

}

When would a cloned object not be its source, i.e. when will a cloned keyevent not be the type of keyevent?

Edit: Furthermore, why does the .clone() object give an Object? Does this have to do with the limitations of the Java language?

I'm using Eclipse Mars (4.5.2) with Java 1.8.0_91.

Boann
  • 48,794
  • 16
  • 117
  • 146
Nolan Akash
  • 989
  • 8
  • 21
  • 1
    Um, I think only if the `clone()` implementation is broken. The JVM does the clone itself and guarantees that the objects are the same type. – markspace May 17 '16 at 00:24
  • I think it's broken too. It worked for me when using a matrix of int, however, I recently had to create a clone of a matrix of a class I myself created and it did not work. I had to create it and copy each value 1 by 1. – UDKOX May 17 '16 at 00:26
  • I think the problem is that the parameter in your constructor is referred to as an `ArrayList`, but it could be something else wrongly cast into an `ArrayList`, for example a non-generic `List` that can contain anything. Have a look at [this answer](http://stackoverflow.com/a/2693301/5221346). – RaminS May 17 '16 at 00:35
  • Hmm, my IDE doesn't give that warning. I think maybe Eclipse is being a little over zealous here. (I'm also using Java 8, maybe Java 7 can't fully recognize the type conversion there? What version of Java are you using?) – markspace May 17 '16 at 00:36
  • Java 1.8; added version to question – Nolan Akash May 17 '16 at 00:52
  • 1
    *thou shalt not use `.clone()`; tis a wicked and evil thing to do* –  May 17 '16 at 00:59

2 Answers2

1

ArrayList returns a type Object. It will always be the same type as the ArrayList, but you still have to cast. It's a syntax thing.

C.f. ArrayList.clone()

Regarding your second question: yes, originally in Java method return values could not be co-variant. You had to return the exact type as the overridden method. Hence, Object.clone() could only return type Object and that's what its overridden methods must do also.

markspace
  • 10,621
  • 3
  • 25
  • 39
1

This happens because during the runtime JVM can not ensure that clone method() will return a ArrayList<MouseEvent> because of the type ereasure.

Talking about the clone method, you must attent to the following:

By default, java cloning is ‘field by field copy’ i.e. as the Object class does not have idea about the structure of class on which clone() method will be invoked. So, JVM when called for cloning, do following things:

1) If the class has only primitive data type members then a completely new copy of the object will be created and the reference to the new object copy will be returned.

2) If the class contains members of any class type then only the object references to those members are copied and hence the member references in both the original object as well as the cloned object refer to the same object.

Here's the best clone explanation I've ever found. Quick and direct.

Jaumzera
  • 2,305
  • 1
  • 30
  • 44