java:如何修复未经检查的强制转换警告
我有以下代码:java:如何修复未经检查的强制转换警告,java,generics,casting,Java,Generics,Casting,我有以下代码: private HashMap<Class<?>, HashMap<Entity, ? extends Component>> m_componentStores; public <T extends Component> T getComponent(Entity e, Class<T> exampleClass) { HashMap<Entity, ? extends Component> st
private HashMap<Class<?>, HashMap<Entity, ? extends Component>> m_componentStores;
public <T extends Component> T getComponent(Entity e, Class<T> exampleClass)
{
HashMap<Entity, ? extends Component> store = m_componentStores.get(exampleClass);
T result = (T)store.get(e);
if (result == null)
{
throw new IllegalArgumentException( "GET FAIL: "+e+" does not possess Component of class\nmissing: "+exampleClass );
}
return result;
}
我缺少什么来防止出现此警告?
类。您需要的是cast
。嗯,你可以考虑不使用反射。< /P>
更改行:
T result = (T)store.get(e);
致:
在Cast语句上方写入
@SuppressWarnings(“未选中”)
:
@SuppressWarnings("unchecked")
T result = (T)store.get(e);
并添加一条解释性语句,说明为什么可以安全地忽略警告。
扩展了泛型中的
,但实际上不是这样<代码>T!=<代码>?扩展组件,即使T扩展组件
。你所拥有的其实是一个,它有着不同的目的
@SuppressWarnings("unchecked")
T resultT = (T)result;
是的,您的解决方案不是类型安全的-以下两个?
标记之间没有关系:
private HashMap<Class<?>, HashMap<Entity, ? extends Component>> m_componentStores;
当您将组件
强制转换为T
时,编译器会发出警告,因为无法静态检查强制转换。但是,如果您确定数据结构的语义,您可以简单地抑制警告
@SuppressWarnings("unchecked")
T resultT = (T)result;
附言: 您不需要通配符捕获,在您的情况下,以下操作将完全相同:
private HashMap<Class<?>, HashMap<Entity, Component>> m_componentStores;
private HashMap+1,最好在库代码IMO中保留ClassCastException。不过,如果你能证明你的库没有犯类型错误(即setComponent
正确且对称地工作),就没有必要这样做。然后一个抑制警告就行了。@MarkPeters在大多数问题上程序员都会说服自己,他们通常是错的。我认为这在所有库设计人员身上都不是真的,如果是这样的话,他们就不应该编写库。API中有一些未经检查的强制转换示例<代码>集合。清空列表()
浮现在脑海中。我们如何处理泛型?必需:找到MyClass:MyClass@AyadiAkrem无法检查参数化类型。(如果对象属于未参数化的子类,您可以将其强制转换为该子类。或者该对象可能被另一个未参数化类型的对象引用。)忽略该对象是不安全的。让我们假设一个简单的例子:抽象类Animal{public abstract void makeNoice();}
,类Cat扩展Animal{}
和类Dog扩展Animal{}
<代码>狗和猫都是动物(当然是)。现在:class SomeAnimalUtils{public static void makeNoise(Animal-Animal){Dog-Dog=(Dog)Animal;Dog.makeNoice();}}
。让我们假设两者都正确地实现了该方法。现在SomeAnimalUtils.makeNoise()
可能会使用猫
,因为它扩展了想要的动物
,但不能将其强制转换为狗
,而您可以将ClassCastException
猫。好吧,我的示例在这里很愚蠢,但它应该表明您确实需要处理未经检查的强制转换。防止人们在中给猫,但只给狗(这可能是其他狗的超级等级,如小狗或哈士奇狗)。但是如果有人在JVM中意外地给出了Cat
,则抛出异常。这是不好的,因为这意味着SomeAnimalUtils
的程序员没有检查参数,并且hilfself抛出了异常。因此您需要预先检查。为此,请在不安全/未检查的强制转换之前添加以下代码:if(null==animal){抛出新的NullPointerException(“参数‘animal’为null”);}否则if(!(Dog的动物实例)){抛出新的ClassCastException(“参数‘animal’=”+animal.toString()+“不是Dog的实例”);}
。这里您还(必须)处理空引用检查,Java语言允许它作为“objected”参数(=对象的实例或任何接口)传递。如果您不注意空引用,您可能会面临臭名昭著的NPE
风险。仍然是主题:一个好的做法是,让所有公共方法检查其“objected”参数的空引用和有效数据范围,例如,来自数据库的id号通常不能低于1
。-)@罗兰:你说得对,忽略警告应该小心。此强制转换是否保存取决于方法的用例及其上下文,在这种情况下,它几乎取决于用于将值放入映射中的方法。问题中未列出此方法。因此,只有作者才能判断这一点。是否在运行时检查了强制转换?
@SuppressWarnings("unchecked")
T resultT = (T)result;
private HashMap<Class<?>, HashMap<Entity, Component>> m_componentStores;