简体   繁体   中英

How to initialize a generic array containing generics?

I have the following code:

public class I<T> {
    private T t;
    public I(T t) {
        this.t=t;
    }
}

public class G<T> {
    private I<T> tab[];
    public G() {
        tab=(I<T>[]) new Object[10];
    }
}

Calling G() throws a ClassCastException.

How could I code the G constructor in order to initialize tab?

tab=(I<T>[]) new I<?>[10];

是答案,但对我来说仍然很神秘!

To hopefully demystify your own answer a bit: be aware, that java implements generics via erasure, ie the compiler basically does some compile time checks, and then discards the generics.

So, from the runtime point of view, your first approach boils down to:

I[] tab = (I[]) new Object[10];

As array types are really distinguished classes, you get a class cast exception here, as I[].class is not the same as Object[].class.

Your second approach is (generics discarded):

I[] tab = (I[]) new I[10];

... no problems here.

Tab is an array of I. I is an Object, but a simple Object created by new Object() is not a I. That explains why the first way produced an error. You must create a array of I to initialize tab .

But that's not all: java generics use type erasure . That means that at run time the compiler does not know what T is. tab = new I<T>[10]; is executed at run time when T has no meaning any more, hence the error.

The solution is to create an array of I of any ( new I<?> ) or an array of I<Object> or even use the old (pre-generic) syntax new I[10] .

That's not asked here, but when you really need to know the type of the parameter in a generic, the common idiom is to pass explicitely the class in constructor or with a setter so that the generic object can use it. Code could be:

class G<T> {
    private I<T> tab[];
    private Class<T> clazz;
    ...
    public G(Class<T> clazz) {
        this.clazz = clazz;
        tab = new I[10];
        // here we can use the type of T from clazz by reflexion...
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM