2

This code works correctly and print out number 120. However, if I uncomment the line in the main function.

The code is throwing an exception: Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Comparable; cannot be cast to [Ljava.lang.Double; at General.main

I searched and found several discussion on generics array in java. People acknowledged the treatment of generics array is not very well in java. But I still feel very bad about this code: print out a line in different places will have different consequences, (execution correctly versus throw an exception).

Could someone please comment on this code and advise if there is any simple fix to the exception related to the println code in the main function?

Here is my code :

public class General<Key extends Comparable<Key>> {
    public Key[] keys;      
    @SuppressWarnings("unchecked")
    public General(int NMAX) {
        keys = (Key[]) new Comparable[NMAX];
        System.out.println(keys.length);
    }
    public static void main(String[] args){
    General<Double> g = new General<Double>(120);
    //      System.out.println(g.keys.length);
    }
}


System.out.println(g.keys.length);
3
  • Is there some reason you cannot use a List instead of an Array? That is, something like private List<Key> keys = new ArrayList<Key>(); - then you could make the class General<Key> Commented Mar 3, 2014 at 20:43
  • @Elliott's inquiry is pretty reasonable. The short answer is the example snippet isn't very type safe. The Lists will take care of this for you. Commented Mar 3, 2014 at 20:48
  • ArrayList will surely solve the problem, but I am looking for deeper understanding of why my approach failed, as explained by people below. Commented Mar 3, 2014 at 23:13

2 Answers 2

2

The reason you get the exception in a seemingly strange place is because of erasure. Erasure of Key is Comparable so the cast here actually never happens at run time:

keys = (Key[]) new Comparable[NMAX];

But as you've observed, a cast does happen when you retrieve the array from outside the object. A Comparable[] is not a Double[] so you get the exception. As long as you don't access the array outside the class, the way you're doing it probably won't cause a problem.

The "safer" idiom is to make the array non-generic by making its declaration a Comparable[]. Then you:

  • Ensure that only Key can be put in the array.
  • Make the unchecked cast on a retrieval call.

Something like this:

@SuppressWarnings("rawtypes")
public class General<Key extends Comparable<Key>> {
    private Comparable[] keys;

    public General(int NMAX) {
        keys = new Comparable[NMAX];
    }

    public void set(int ind, Key k) {
        keys[ind] = k;
    }

    @SuppressWarnings("unchecked")
    public Key get(int ind) {
        return (Key)keys[ind];
    }
}

That's type safe and it's the way the JDK does it.

Another way is to have the client provide the array:

public class General<Key extends Comparable<Key>> {
    private Key[] keys;

    public General(Key[] keys) {
        this.keys = keys;
    }
}

You should also consider using a List instead because they do all this stuff for you and are fully generic. You can just do new ArrayList<Key>().

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for clarification here. I was following the algorithm courses from Prof SedgeWick and trying not to use complicated generics to achieve simple stuff.:)
1

You could try to keep the keys as a Comparable[] array.

public class General<Key extends Comparable<Key>> {
public Comparable[] keys;      // keys[i] = priority of i

public General(int NMAX) {
    keys = new Comparable[NMAX];
    System.out.println(keys.length);
}

public static void main(String[] args) {
    General<Double> g = new General<Double>(120);
    System.out.println(g.keys.length);
}
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.