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?

0

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Would this be generally safe? Or will the cast and use of object potentially cause corner cases?
@Zimm3r You are right. It will probably not be. I have updated my answer.
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

3 Comments

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 it was merely an example. The main concept is that there is information missing that isn't available.
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.
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]

3 Comments

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).
This is using Java reflection to construct the object array. It's how you can do it.
@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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.