3

I have a generic K and wish to create an empty array so I type

private K[] keys   = new K[0];

However eclipse says "Cannot create an generic array of K"

Have I missed something? You can create an empty array of int, is this something generics can't do?

Zimm3r
  • 3,177
  • 3
  • 30
  • 48

3 Answers3

2

You cannot create arrays of generics in Java. A workaround would be:

keys = (K[])new Object[size]; 

Although this will generate a compiler warning.

Generally, this is not a good practice and it is not safe to do it. See this thread for more.

However, if you just can't avoid it, it should only be used with new as this casting of an Object array to K[] might be used to insert stuff you won't like.

Update:

But really, as you can see in this answer java.lang.reflect.Array.newInstance() is probably the safer way using the reflection library.

Community
  • 1
  • 1
Artem Tsikiridis
  • 642
  • 6
  • 11
1

What if K is abstract? How would the executor know how to fill any missing methods?

Also, due to type-erasure upon compilation, you can't tell what class K actually is without comparing it to others, which would require an instance.

Type erasure

Obicere
  • 2,999
  • 2
  • 17
  • 29
  • 1
    An abstract `K` isn't a problem, any more than it's a problem to create a `List[]`. You can create an array of an abstract class (or interface), because the array doesn't need to know what its elements' implementations are. – yshavit Dec 13 '13 at 02:02
  • @yshavit it was merely an example. The main concept is that there is information missing that isn't available. – Obicere Dec 13 '13 at 02:05
  • Yes, but it has everything to do with erasure (which you linked to) and nothing to do with `K` potentially being abstract. That's all I was saying. – yshavit Dec 13 '13 at 03:07
1

You can use the Array.newInstance() method to achieve something like this; consider

public class Question<K> {
  private K[] keys;

  @SuppressWarnings("unchecked")
  public Question(Class<? extends K> cls, int size) {
    this.keys = (K[]) Array.newInstance(cls, size);
  }

  public K[] getKeys() {
    return keys;
  }

  public static void main(String[] args) {
    Question<String> question = new Question<String>(
        String.class, 10);
    String[] keys = question.getKeys();
    keys[0] = "Hello";
    keys[1] = "World";
    keys[2] = "Goodbye";
    keys[3] = "I must";
    keys[4] = "be Going";
    keys[5] = "Now";
    keys[6] = "Parting";
    keys[7] = "is";
    keys[8] = "such";
    keys[9] = "sweet sorrow";
    System.out.println(Arrays.toString(question
        .getKeys()));
  }
}

Here this prints

[Hello, World, Goodbye, I must, be Going, Now, Parting, is, such, sweet sorrow]
Elliott Frisch
  • 183,598
  • 16
  • 131
  • 226
  • Pretty sure not allowed to use that. We are not allowed to use an of the builtin java storage classes. (Though I assume we can use array sense otherwise it would be rather hackish to deal with pointers etc). – Zimm3r Dec 13 '13 at 02:13
  • This is using Java reflection to construct the object array. It's how you can do it. – Elliott Frisch Dec 13 '13 at 02:17
  • @ElliottFrisch You are right, It can be done with `java.lang.reflect.Array` as well. In my answer I just thought that `new K[size]` cannot be said in java, and the immediate workaround that came to mind :) This is definitely safer. – Artem Tsikiridis Dec 13 '13 at 02:30