views:

34

answers:

3

How do I check generic subtypes passed as parameter?

For example:

public class A<T> { public T get();}
public class AString extends A<String> {}
public class ADate extends A<Date> {}

public void checkparam(List<? extends A<?>> params) {
///Want to check if params is of type List<AString> or List<ADate> ?
}

Is it possible? What part I am not understanding?

+1  A: 

It is not possible because generic type information like that is erased and not available at runtime. At runtime, all that is known is that the parameter to checkparam is a List.

ColinD
I thought so :)
newtoflex4
A: 

I don't believe you can do it directly on the list. You could do a check on the first element:

if (!params.isEmpty() && params.get(0) instanceof AString) {
   // it's List<AString>
}
...

Not pretty and won't work on empty lists, but should work otherwise.

Kaleb Brasee
did it this way.. but the compiler warns "Type safety: Unchecked cast from List<capture#7-of ? extends A<?>> to List<AString>" when casted to "(List<AString>) params".
newtoflex4
This isn't really a viable choice. For example, what if there's another implementation of `A<String>` called `AOtherString` and the list is actually a `List<A<String>>` that contains some of both? If you try to cast every `A<String>` to `AString`, it's going to fail. What if it's actually a `List<A<?>>` that has `ADate` in it as well?
ColinD
A: 

This is made clear by trying to compile the following code:

import java.util.Date;
import java.util.List;

public class A<T> { 
    private T value;

    public T get() {
        return value;
    }

    public void checkparam(List<AString> list) {

    }

    public void checkparam(List<ADate> list) {

    }
}
class AString extends A<String> {}
class ADate extends A<Date> {}

which produces the following output from javac:

$ javac A.java 
A.java:11: name clash: checkparam(java.util.List<AString>) and checkparam(java.util.List<ADate>) have the same erasure
    public void checkparam(List<AString> list) {
                ^
A.java:15: name clash: checkparam(java.util.List<ADate>) and checkparam(java.util.List<AString>) have the same erasure
    public void checkparam(List<ADate> list) {
                ^
2 errors
pansapien