Error: Generic Array Creation

125,217

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.

Share:
125,217

Related videos on Youtube

Luron
Author by

Luron

Updated on April 10, 2020

Comments

  • Luron
    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
      Chris J over 13 years
      Can you post the Exception/Error
    • Kirk Woll
      Kirk Woll over 13 years
      I 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
      Luron over 13 years
      already tried reading that post. it doesn't help me
    • Kirk Woll
      Kirk Woll over 13 years
      the 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 just Object 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
      Aniketos over 11 years
      I 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
      Christian about 8 years
      PCB<?>[] res = new PCB<?>[100]; is possible
  • newacct
    newacct over 13 years
    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
  • brady
    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
    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 an Object[].
  • brady
    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
    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 an Object[] is basically guaranteed to throw a runtime error, so why the heck would you bother returning anything else?
  • brady
    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
    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
    WestCoastProjects about 3 years
    This does not work for primitive types? I am looking for a generic solution handling int,long,double