In a general sense, this is not possible
Due to type erasure, a Java Set
does not have a generic type at runtime. Generics act as compile-time checks on the objects passed into methods, but consequently the specific values are not available at runtime. A Set<String>
is the same class as a Set<Map<Integer, Thread>>
and the same class as a bare Set
.
Potential workaround with class parameter
If you really need to know this, you could change the signature of your method to be:
public <X> boolean myMethod(Set<X> mySet, Class<X> clazz)
Now you have a Class
instance available at runtime, which is guaranteed to be compatible with X
. This you can introspect (e.g. String.class.isAssignableFrom(clazz)
).
There are two drawbacks to this approach: firstly, you'll have to explicitly pass in the extra parameter each time the method is called. Secondly, if A
and B
can be subclasses of one another, this is not going to work; you could pass in e.g. B.class
even when the generic parameter was A
.
However, this feels like a code smell
You shouldn't be trying to do fundamentally different things based on a generic parameter. Instead of switching behaviour in your method here, do something different within the classes A and B:
public<X> boolean myMethod(Set<X> mySet)
{
boolean result = false;
for (X x : mySet) {
result &= x.doSomething();
}
return result;
}
class A implements MyDoSomethingInterface {
public boolean doSomething() {
// Here you put the logic for "if X is A"
}
}
class B implements MyDoSomethingInterface {
public boolean doSomething() {
// Here you put the logic for "if X is B"
}
}
And if your reaction is that this won't work because A and B are built-in classes, you'll need to wrap them in your own domain objects (which is the correct approach anyway because you want to associate this extra behaviour with them).