Java For Each语句中的Cast元素

时间:2010-03-19 20:14:38

标签: java foreach casting

是否有可能(甚至可取)在语句本身中为每个语句强制转换检索到的元素?我知道列表中的每个元素都是<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;
    ...
}

5 个答案:

答案 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;
                }
            };
}