Reputation: 43
I had a problem creating some arrays.
Here is the code
Predicate<Integer[]>[] endOfLine = {
curPoint -> curPoint[0]==r2,
curPoint -> curPoint[0]==c2,
curPoint -> curPoint[0]==r1,
curPoint -> curPoint[0]==c1
};
Consumer<Integer[]>[] move = {
curPoint -> { curPoint[0]++; },
curPoint -> { curPoint[1]++; },
curPoint -> { curPoint[0]--; },
curPoint -> { curPoint[1]--; }
};
and eclipse (maybe compiler?) said:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot create a generic array of Predicate<Integer[]>
I Googled, and found that generic type parameter array can't be made in Java.
I read about compile time and runtime, and I thought it may be not my problem.
I saw some code which compile compiled:
List<Integer>[] arrayOfLists = new ArrayList[2];
ArrayList<Integer[]> lists =new ArrayList<>();
ArrayList<Consumer []> [] lists = new ArrayList[5];
Predicate<Integer[]>[] p = new Predicate[5];
p[0] = a -> a[0] == 0;
Predicate<Integer[]>[] pp = { a -> a[0] == 0 }; //cant be compile
and I read oracle doc and found this:
"Cannot Create Arrays of Parameterized Types"
I concluded my shortcut syntax, {} is the problem. Shortcut syntax create code with parameterized type. Is this correct?
Upvotes: 4
Views: 3451
Reputation: 21124
You can't create a generic array in Java. Arrays are reifiable types, and carry their type information at runtime whereas generics are non reifiable, and their type information is erased after the compile time due to erasure. This is due to the implementation of the type system in java and even though this causes some rough edges and corner cases, it eases the evolution of code into generics. Since generic type information is erased, you don't have them at runtime and that's why you can't create a generic array in java.
There are two solutions to circumvent the issue you are facing. You can either create an Object array and cast it to the generic type you need.
final T[] arr = (T[]) new Object[n]
or else
final Object[] arr = new Object[]
You can do the cast when you get the items from this array like this
T itm = (T) arr[1];
Both of the above approaches work if you don't return this internal array.
However, if you are returning the internal array, you need to create it reflectively, since you need to maintain the proper reifiable type.
static <T> T[] createArr(Class<T> clz) {
return (T[]) Array.newInstance(clz, 5);
}
Upvotes: 3