views:

108

answers:

2

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

+2  A: 

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.

erickson
yea 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
newacct
@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.
erickson
@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 an `Object[]`.
Mark Peters
@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.
erickson
@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 an `Object[]` is basically guaranteed to throw a runtime error, so why the heck would you bother returning anything else?
Mark Peters
@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.
erickson
@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.
Mark Peters
A: 

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.

Mark Peters