tags:

views:

252

answers:

3

I'm still trying to get my head around using Java's generics. I have no problems at all with using typed collections, but much of the rest of it just seems to escape me.

Right now I'm trying to use the JUnit "PrivateAccessor", which requires a Class[] argument with a list of all the argument types for the private method being called. In Java 1.4, I'd define that as

Class[] args = new Class[] { Collection.class, ArrayList.class };

but the actual code is defined to now take the arguments

myMethod(Collection<MyClass1> first, ArrayList<MyClass2> second)

I tried to change the definition of args to be

Class<? extends Object>[] args = new Class<? extends Object>[] 
{ Collection<MyClass1>.class, ArrayList<MyClass2>.class };

But Eclipse puts a red marker on the closing >s, and says it's expecting "void" at that point. Can I do this using generics, or shouldn't I bother?

+2  A: 

This is the correct syntax:

Class<?>[] paramTypes = new Class[]{ Collection.class, ArrayList.class };
erickson
+5  A: 

The first problem you have is that you should be using

Class<?>[] args = new Class[]

instead of

Class<? extends Object>[] args = new Class<? extends Object>[]

This explains why.

Your second problem is that you should be using

{ Collection.class, ArrayList.class };

instead of

{ Collection<MyClass1>.class, ArrayList<MyClass2>.class };

This is because XXX.class is evaluated at runtime, after type erasure has been performed, so specifying the type argument is useless, hence forbidden.

I highly recommend the FAQ from which I've linked the two explanations above for an "earthly" take on Java generics that will clarify most questions.

bdumitriu
+1  A: 

You may want to read Angelika's FAQ for more explanation on why creation of arrays of concrete parameterized types is not allowed.

yc

yclian
Just noticed that I double-posted the link bdumitriu has referenced to. But this one will bring you straight to the subject we're on.
yclian