Error: Generic Array Creation
Solution 1
You can't create arrays with a generic component type.
Create an array of an explicit type, like Object[]
, instead. You can then cast this to PCB[]
if you want, but I don't recommend it in most cases.
PCB[] res = (PCB[]) new Object[list.size()]; /* Not type-safe. */
If you want type safety, use a collection like java.util.List<PCB>
instead of an array.
By the way, if list
is already a java.util.List
, you should use one of its toArray()
methods, instead of duplicating them in your code. This doesn't get your around the type-safety problem though.
Solution 2
The following will give you an array of the type you want while preserving type safety.
PCB[] getAll(Class<PCB[]> arrayType) {
PCB[] res = arrayType.cast(java.lang.reflect.Array.newInstance(arrayType.getComponentType(), list.size()));
for (int i = 0; i < res.length; i++) {
res[i] = list.get(i);
}
list.clear();
return res;
}
How this works is explained in depth in my answer to the question that Kirk Woll linked as a duplicate.
Solution 3
Besides the way suggested in the "possible duplicate", the other main way of getting around this problem is for the array itself (or at least a template of one) to be supplied by the caller, who will hopefully know the concrete type and can thus safely create the array.
This is the way methods like ArrayList.toArray(T[])
are implemented. I'd suggest you take a look at that method for inspiration. Better yet, you should probably be using that method anyway as others have noted.
Related videos on Youtube
Luron
Updated on April 10, 2020Comments
-
Luron about 4 years
I don't understand the error of Generic Array Creation.
First I tried the following:public PCB[] getAll() { PCB[] res = new PCB[list.size()]; for (int i = 0; i < res.length; i++) { res[i] = list.get(i); } list.clear(); return res; }
Then I tried doing this:PCB[] res = new PCB[100];
I must be missing something cause that seems right. I tried looking it up I really did. And nothing is clicking.
My question is: What can I do to fix this?
the error is :
.\Queue.java:26: generic array creation PCB[] res = new PCB[200]; ^ Note: U:\Senior Year\CS451- file uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 1 error
Tool completed with exit code 1
-
Chris J over 13 yearsCan you post the Exception/Error
-
Kirk Woll over 13 yearsI am assuming that
PCB
is a generic type parameter and thus, what you are doing is impossible in Java due to type-erasure. If that is all true, you should click on the link I marked this a dup of as it provides a workaround. -
Luron over 13 yearsalready tried reading that post. it doesn't help me
-
Kirk Woll over 13 yearsthe sad truth is that Java made the conscious decision to explicitly prevent this syntax from working. Java implements type-erasure, which means that the type argument
PCB
actually has no meaning at runtime (or technically, it does, but it's probably justObject
which wouldn't do you any good). There are two ways to circumvent this restriction. Both are explained in detail at the link I referenced. Let me know what specific part of that solution you are having trouble with. -
Aniketos over 11 yearsI faced with the same problem. PCB is not likely a generic class (I think it's an internal class), but Java somehow think it is generic. Anybody know how to fix this?
-
Christian about 8 yearsPCB<?>[] res = new PCB<?>[100]; is possible
-
-
newacct over 13 yearsyea but when you return it to the outside, and the caller assigns it to a variable of type PCB[]. boom you will get a class cast exception
-
brady over 13 years@newacct - That won't necessarily happen. It depends on the calling context. But it can happen. That's what I meant by "Not type-safe," and why I recommended against it.
-
Mark Peters over 13 years@erickson: It will eventually happen at some point as the recursion unfolds. Generics always become concrete at some point or else no work would ever get done. The only way this would reasonably work is if the result is never actually used as an array of the actual type of
PCB
. In which case it's much better to just declare yourself as returning anObject[]
. -
brady over 13 years@Mark Peters - No, there are many instances where you know that the resulting array will not "escape" to a context where it's used as anything but an
Object[]
. But, of course, it would be best not to try to shoe-horn generics into an array. -
Mark Peters over 13 years@erickson: Exactly, and since that's the case, then just return an
Object[]
since it's type-safe and doesn't limit usage at all. Any usage that uses the result as anything but anObject[]
is basically guaranteed to throw a runtime error, so why the heck would you bother returning anything else? -
brady over 13 years@Mark Peters - I wouldn't. That's why I recommend using a
List<PCB>
instead. But I include it as a direct response to the OP's explicit question. -
Mark Peters over 13 years@erickson, actually, I found a usage example where it's not strictly stupid. If the generic array remains encapsulated in a collection (ArrayList, e.g.) then access to and from the array is performed through generics alone and it works. Wasn't thinking of keeping it around as an instance variable.
-
WestCoastProjects about 3 yearsThis does not work for primitive types? I am looking for a generic solution handling int,long,double