我的情况是,我有功能
public static MyInterface doSomething() {...}
和班级
MyList<O extends MyObject> extends MyListObject<O> implements MyInterface
和:
MyObjectA
扩展为MyObject
] >>MyListObject
仅实现接口Collection<O>
和List<O>
我的问题是下面的代码
MyList<MyObjectA> var = (MyList<MyObjectA>)doSomething();
产生一个
Type safety: Unchecked cast from MyInterface to MyList<MyObjectA>
警告。为什么呢?我的意思是
doOperation()
返回MyInterface
类型,并且MyList
实现了所述接口...
我希望我的代码示例能够解释所有类和接口之间的完整关系,并且我不会错过任何内容。
我的情况是,我有一个函数public static MyInterface doSomething(){...}和一个类MyList
MyInterface
是MyList<>
,但我可以肯定它不是–尽管您没有显示MyInterface
的实际定义。比喻地说,您正在尝试将每个工具(MyInterface
)视作锤子(MyList<>
)。
如果您确定doSomething()
始终返回MyList
,则可以使用@SuppressWarnings("unchecked")
批注标记包含强制类型转换的方法。但是,为什么首先要声明doSomething()
返回更通用的MyInterface
?
interface Flying {
void fly();
}
class Bird extends Animal implements Flying {
...
}
List<Flying> listFlying();
List<Flying> list = listFlying();
如果确实只使用接口的方法,则可以使用:
list.forEach(flying -> flying.fly());
否则,安全需要铲铲:
List<Bird> birds = list.stream() // Or listFlying().stream() .filter(Flying.class::isInstance) .map(Flying.class::cast) .collect(Collectors.toList());
<…>
,除非它是<?>
。 (此规则有一些例外,但它们是特殊情况,在这里不相关。)泛型是一种编译时类型检查机制。在运行时,由于类型擦除,不存在MyList<MyObjectA>
类。只有一个MyList
类。
这意味着编译器只能生成此代码:
(MyList<?>) doSomething();
试图迫使编译器假定结果具有特定的泛型类型是不安全,,因为将执行强制转换的代码无法对此进行检查。因此,您的演员表是未经检查的演员表。
safe
的方法是执行非泛型转换:MyList<MyObjectA> var = new MyList<>(); MyList<?> list = (MyList<?>) doSomething(); for (Object element : list) { var.add((MyObjectA) element); }
注意:
var
现在是Java中的保留关键字。您应该避免将其用作变量名。