避免涉及类的运行时传递的一般情况的不安全转换
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 AutoKeyMap.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();
}
}
}
在上面的代码示例中,在不添加 @SuppressWarnings
(如果有)的情况下,防止给定警告的正确方法是什么?
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 AutoKeyMap.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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以通过执行以下操作暂时修复代码:
但是如果您需要在 AutoKeyMap 中实现类似的方法
,那么它将再次中断。问题是,一旦开始对类类型进行运行时检查(就像在
if(keyType == Integer.class)
中所做的那样),Java 编译器就无法静态地确保类型正确。因为您可以实例化new AutoKeyMap(ClasskeyType)
然后编写这显然会破坏,因此静态检查泛型类型的全部意义将会丢失。
通常,像您这样涉及动态类型转换的所有问题都超出了泛型范围,因此您必须忍受未经检查的转换,并且只需确保编写足够的单元测试并确保您的代码可以正常工作并且不会抛出 ClassCastException在所有场景中。
You can fix your code temporarily by doing this:
But if you need to implement a method in
AutoKeyMap
likethen 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 instantiatenew AutoKeyMap<Boolean>(Class<Boolean> keyType)
and then writewhich 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.