I have a GenericList class that must initialise an array with type but it force me to declare it as Object in compile time. When I declare the generic as String in Main, the program stops with ClassCastException when i assign the list.items to a variable called items, which compile time also recognise it as String[]. Error is like this:
Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.String; ([Ljava.lang.Object; and [Ljava.lang.String; are in module java.base of loader 'bootstrap') at com.advanced.Main.main(Main.java:51)".
Why and how to solve this? Thank you.
public class GenericList<T> { public T[] items = (T[]) new Object[10]; private int count; public void add(T item){ items[count++] = item; } public T get(int index){ return items[index]; } public T[] getItems() { return items; } }
public class Main { public static void main(String[] args) { var list = new GenericList<String>(); list.add("a"); list.add("b"); var items = list.items; for(var item: items){ System.out.println(item); } } }
Advertisement
Answer
You must to inject explicitly the array constructor for T
type.
E.g. move your new T[10]
as
static class GenericList<T> { final public T[] items; private int count; public GenericList(IntFunction<T[]> arrayConstructor) { items = arrayConstructor.apply(10); }
And create the object injecting the constructor
var list = new GenericList<>(String []::new);
Now all works
a b null null null null null null null null
(Note: with T[] items = (T[]) new Object[10]
you are not creating a T
array, you are creating an Object
array casting to a T
array, which is incorrect)