import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
class Foo {}
class Bar {}
interface MyValidMap extends Map<Foo, Set<Bar>> {}
class Ideone {
public final HashMap<Foo, HashSet<Bar>> good = null;
public final Map<Foo, Set<Bar>> better = null;
public final String notAMap
= null; public final Map
<String, Set
<Bar
>> badKey
= null; public final Map<Foo, String> badValue = null;
public final Map<Foo, Set<String>> badSetElems = null;
public final MyValidMap noTypeParamMap = null;
for (Field field
: Ideone.
class.
getFields()) { System.
out.
println(field.
getName() + " - " + fieldMatches
(field
)); }
}
if (!Map.
class.
isAssignableFrom(mapField.
getType())) { return "Field is not a Map";
}
if (!(mapField.getGenericType() instanceof ParameterizedType)) {
// We know it's a map, but it doesn't have type params. Probably something
// like this: class MyStringMap implements Map<String, String>. You can do
// something with getGenericInterfaces() but this seems so unlikely that
// it could just be ignored.
return "TODO";
}
final ParameterizedType mapType = (ParameterizedType) mapField.getGenericType();
final Type keyType = mapType.getActualTypeArguments()[0];
final Type valueType = mapType.getActualTypeArguments()[1];
if (Foo.class != keyType) {
return "Map's key type is not Foo";
}
if (!(valueType instanceof ParameterizedType)) {
// Same problem as above. May be a Set without type params
return "Map's value is (probably) not a Set";
}
final ParameterizedType pValueType = (ParameterizedType) valueType;
final Class<?> valueClass = pValueType.getRawType() instanceof Class ?
((Class<?>) pValueType.getRawType()) :
Ideone.class.getClassLoader().loadClass(
pValueType.getRawType().getTypeName()
);
if (!Set.
class.
isAssignableFrom(valueClass
)) { return "Map's value is not a Set";
}
final Type setElemType = pValueType.getActualTypeArguments()[0];
if (setElemType != Bar.class) {
return "Set's elements are not Bars";
}
return "Looks good";
}
}