Casting between an object of a generic type "T" and an object of a generic type "<T extends Comparable <T>>"
I implemented the ArrayLinearList class as follows
public class ArrayLinearList<T> implements LinearList<T>, Iterable<T> which contains a class member
protected T[] element To extend the functionality of the class, I create a new class that inherits from the first
class SuperList<T extends Comparable<T>> extends ArrayLinearList<T> Here I guarantee that type T implements the Comparable interface (this cannot be changed).
In the SuperList class, I have the following method
public void replace( int pedro, T maria ){ element[ pedro ] = maria; }
The method line generates the following error:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable; But if I declare the class as follows, I no longer have this problem (but in this way I can no longer compare class objects)
class SuperList<T> extends ArrayLinearList<T>{ I would be grateful for any help in solving this problem. I am not allowed to modify the \ [ArrayLinearList class, just the SuperList class.
Thanks in advance.
Based on the exception, it looks like you are initializing element with new Object[someLength] and doing unchecked selection to T[] . This probably happens in an ArrayLinearList . The problem is that in this code:
element[ pedro ] = maria; element treated as Comparable[] at runtime, and Object[] not Comparable[] .
There are many existing posts related to creating a shared array, but your problem is interesting in that you threw inheritance into the mix (with narrowing the boundaries of the type parameter). The best solution seems to interact only with element in the ArrayLinearList class. Make it private and expose getters and setters. This should avoid run-time crashes like this (which should be considered to avoid uncontrolled deviations when executing, such as (T[])new Object[someLength] ).
For example:
public class ArrayLinearList<T> implements LinearList<T>, Iterable<T> { private final T[] elements; public ArrayLinearList(final int length) { @SuppressWarnings("unchecked") // won't be exposed outside this class final T[] withNarrowedType = (T[])new Object[length]; elements = withNarrowedType; } public final void set(final int index, final T element) { elements[index] = element; } } EDIT: I just noticed your disclaimer, "I am not allowed to modify the ArrayLinearList class ArrayLinearList only the SuperList class SuperList " Well, that is unsuccessful because the author of ArrayLinearList wrote unsafe code. But the question is why a method like SuperList.replace should interact with the array directly (or even exist). It seems like it just assigns a new element to the specified index - is there an ArrayLinearList method you can use to do this?
If all else fails, here is a workaround:
((Object[])element)[pedro] = maria; But this is a terrible solution that paves the way for the main problem.