我试图在for循环
中自动将对象列表的每个元素转换为正确的类型public boolean equals(Object obj) {
if(obj == null || !(obj instanceof KGramPostingsEntry)) {
return false;
}
KGramPostingsEntry other = (KGramPostingsEntry) obj;
if(other.tokenID == this.tokenID) {
return true;
}
return false;
}
正如我在代码中发布的那样," for statement"显示错误:
类型不匹配:无法转换元素类型捕获#1-of?到A
我尝试过其他解决方案:
class A {
}
class B {
void sampleMethod() {
List<?> l1 = //initialized somewhere;
/*
I do know perfectly l1 got elements of Class A
I just could not declare List<A> for other (generic types) reasons
*/
for (A el: l1) { // Type mismatch: cannot convert from element type capture#1-of ? to A
System.out.println(el);
}
}
}
现在警告结果:
类型安全:从列表到列表的未选中投射
最后,我找到了一个工作(但在我看来不合适)的解决方案,即在内部投射:
for (A el: (List<A>)l1)
为什么我不能在for语句中做这种投射?真的没办法干净利落吗?
答案 0 :(得分:2)
真的没办法干净利落吗?
如果您使用通配符声明List
:
List<?> l1 = //initialized somewhere;
如果没有任何警告,你将无法将其元素强制转换为特定类型 你试图做的事情会破坏仿制药的目的。
您在评论中写道:
我无法为其他(通用类型)原因声明
List<A>
没有通配符或绑定的泛型变量(如List<A>
)有一些限制。众所周知,您无法为List<B>
分配B
,其中A
是List<? extends A>
的子类。但是有另一种方法可以使它作为List<A>
工作,同时它还有其他一些限制。
事实上,在声明A
时,您没有描述遇到的问题。因此很难提供具体的解决方案
但我认为,如果仅操作列表中的List<A>
个实例,则应声明更具体的类型。
因此,如果{{1}}导致代码出现问题,请深入研究此问题,如果“无法解析”,为什么不提出相关问题。
答案 1 :(得分:1)
如果以下内容,&#34;我确实知道l1得到了A类和#34;的元素,然后尝试:
List<?> l1 = ...
@SuppressWarnings("unchecked")
List<A> l2 = (List<A>) l1;
for (A a: l2) { ... }
但更简洁的方法是迭代原始列表,检查元素类型,然后在没有警告的情况下进行投射:
for (Object generic: l1) {
if (generic instanceof A) {
A a = (A) generic; // without warnings
// do stuff
} else if (generic == null) { // if nulls possible
// do stuff
} else {
throw new IllegalArgumentException("item not of class A");
}
}
答案 2 :(得分:0)
在循环中使用铸造元素的解决方案是完全合适的。 List<?>
是未知列表,其元素类型与任何内容匹配。所以你唯一能确定的是所有项目都是对象,所以你这样做。这总是安全的,因为无论集合的实际类型如何,它都包含对象。您可以参考Oracle Generics tutorial中的类似案例,该案例被视为良好的代码示例。
希望它有所帮助!