Avoiding unsafe cast for generic situation involving runtime passing of class
public class AutoKeyMap<K,V> {
public interface KeyGenerator<K> {
public K generate();
}
private KeyGenerator<K> generator;
public AutoKeyMap(Class<K> keyType) {
// WARNING: Unchecked cast from AutoKey开发者_如何学PythonMap.IntKeyGen to AutoKeyMap.KeyGenerator<K>
if (keyType == Integer.class) generator = (KeyGenerator<K>) new IntKeyGen();
else throw new RuntimeException("Cannot generate keys for " + keyType);
}
public void put(V value) {
K key = generator.generate();
...
}
private static class IntKeyGen implements KeyGenerator<Integer> {
private final AtomicInteger ai = new AtomicInteger(1);
@Override public Integer generate() {
return ai.getAndIncrement();
}
}
}
In the code sample above, what is the correct way to prevent the given warning, without adding a @SuppressWarnings
, if any?
You can fix your code temporarily by doing this:
private KeyGenerator<?> generator;
public AutoKeyMap(Class<?> keyType) {
// WARNING: Unchecked cast from AutoKeyMap.IntKeyGen to AutoKeyMap.KeyGenerator<K>
if (keyType == Integer.class) generator = new IntKeyGen();
else throw new RuntimeException("Cannot generate keys for " + keyType);
}
But if you need to implement a method in AutoKeyMap
like
K generate(){
return generator.generate();
}
then it will break again. The problem is as soon as you start doing runtime checking of class types (like you do in if(keyType == Integer.class)
) then Java compiler has no way of statically ensuring that type will be correct. Because you can instantiate new AutoKeyMap<Boolean>(Class<Boolean> keyType)
and then write
if(keyType == Boolean.class){
generator = new IntKeyGen();
}
which will obviously break, and therefore the whole point of statically checked generic types will be lost.
Usually all problems like yours that involve dynamic type casting are beyond generics, so you have to live with unchecked casts, and just make sure you write enough unit tests and make sure your code works and does not throw ClassCastException
in all scenarios.
精彩评论