是否有可能(甚至可取)在语句本身中为每个语句强制转换检索到的元素?我知道列表中的每个元素都是<SubType>
类型。
即:
List<BaseType> list = DAO.getList();
for(<SubType> element : list){
// Cannot convert from element type <BaseType> to <SubType>
...
}
而不是:
List <BaseType> list = DAO.getList();
for(<BaseType> el : list){
<SubType> element = (<SubType>)el;
...
}
答案 0 :(得分:17)
你真的知道每个条目都是一个子类型吗? DAO只需要履行List<BaseType>
契约,如果你假设一个子类,那么我认为某些地方出了问题。我可能更专注于让DAO的界面正确,并让它合同返回你想要的东西。
答案 1 :(得分:14)
出于其他人所说的所有理由,你不应该这样做。但是,如果您无法更改界面,则可以执行以下操作:
for (BaseType element : list) {
SubType subType = (SubType)element;
...
}
据我所知,这是实现此目的的唯一方法,并保持真正的类型安全 - 即不依赖类型擦除来捕获任何问题,直到很久以后它才会发生。
我意识到这并不是你想要的,但它确实处理了演员。
答案 2 :(得分:10)
实际上可以将强制转换与for循环结合起来,如下所示:
List<BaseType> list = DAO.getList();
for (SubType subType : ((List<SubType>) list)){
...
}
或者您可以使用这种稍微清洁的模式:
List<SubType> list = (List<SubType>) DAO.getList();
for (SubType subType : list){
...
}
除非您禁止,否则您将从Java编译器获得未经检查的强制转换警告。第一种形式的效果实际上与在循环中转换每个元素相同。第二种形式还将强制列表的新添加必须符合SubType。
请注意,这不适用于数组,因为数组具有不同的运行时类型。换句话说,BaseType []不能转换为SubType []。您可以使用Arrays API解决此问题,如下所示:
BaseType[] array = DAO.getArray();
for (SubType subType : Arrays.<SubType>asList(array)) {
...
}
答案 3 :(得分:1)
可能,是的!但是上帝保佑,为什么?我在职业生涯中的早期尝试就是这样,而且我已经学会了。对接口进行编程总是有优势的。我总是从初级开发人员处获得有关处理只有子类型需要方法/功能的情况的问题。
说具有方法bark()的Dog子类型的Animal类。他们想要bark()功能。实际的挑战是他们想要一种动物交流行为而不是吠叫()但动物说话()。所以一个新的Cat子类不需要meow()。那么呢: - 我的狗是一个包,但猫没有。答案pack()行为不属于单个狗。 Pack是一个不同的方面,将包传递给所有对象并要求对象加入包。 (访客模式/适配器模式)。我的Wolf类可以使用相同的行为。
我是不是很苛刻,不,如果它只有1次,我很好。如果答案是我不确定,那么你最好通过在接口合同上工作来保证安全。
答案 4 :(得分:1)
如果您不偏爱Google集合,则可以使用transform
方法封装列表。在您的情况下,它将是非常有效和完全合规的。我会把它作为一个包装方法,但正如布莱恩所建议的那样。
public List< SubType > fromDao ( )
{
// Put a comment for maintainer
// Lists from DAO always contain SubTypes
return
Lists.transform(
DAO.getList( ),
new Function< BaseType, SubType >( )
{
public SubType apply ( final BaseType from )
{
return (SybType) from;
}
};
}