Java For Each 语句中的强制转换元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2480316/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cast element in Java For Each statement
提问by Carl Summers
Is it possible (or even advisable) to cast the element retrieved from a for each statement in the statement itself? I do know that each element in list will be of type <SubType>
.
是否可以(甚至建议)转换从语句本身的 for each 语句中检索到的元素?我知道 list 中的每个元素都是 type <SubType>
。
I.E.:
IE:
List<BaseType> list = DAO.getList();
for(<SubType> element : list){
// Cannot convert from element type <BaseType> to <SubType>
...
}
rather than:
而不是:
List <BaseType> list = DAO.getList();
for(<BaseType> el : list){
<SubType> element = (<SubType>)el;
...
}
采纳答案by Brian Agnew
Do you reallyknow that each entry is going to be a subtype ? The DAO simply has to fulfill the List<BaseType>
contract, and if you're assuming a subclass, then I think something is wrong somewhere. I'd perhaps concentrate more on getting the interface to the DAO correct, and have it contractually return what you want.
您真的知道每个条目都将是一个子类型吗?DAO 只需要履行List<BaseType>
合同,如果您假设有一个子类,那么我认为某处有问题。我可能会更专注于让 DAO 的接口正确,并让它按照合同返回你想要的东西。
回答by questzen
Possible, yes! but god forbid, Why? My early attempts in my career did that and I have learnt. Programming to interfaces always has an advantage. I always get questions from junior developers about handling cases where only subtypes have the methods/functionality required.
可能,是的!但上帝保佑,为什么?我在职业生涯中的早期尝试就是这样做的,我已经学会了。对接口编程总是有优势的。我总是从初级开发人员那里得到有关处理只有子类型具有所需方法/功能的情况的问题。
Say Animal class with Dog subtype having method bark(). They want bark() functionality. The actual challenge is that they want a behaviour of animal communication not bark() but animal speak(). So a new Cat sub class would not require meow(). What about this then:- My dog's form a pack, but cats don't. The answer pack() behaviour is not owned by a single dog. Pack is a different aspect, pass a pack to all objects and ask the objects to join the pack. (Visitor pattern/Adapter pattern). My Wolf class can use the same behaviour.
说带有方法 bark() 的 Dog 子类型的 Animal 类。他们想要 bark() 功能。实际的挑战是他们想要一种动物交流的行为,而不是 bark() 而是动物 speak()。所以新的 Cat 子类不需要 meow()。那怎么办:- 我的狗会成群结队,但猫不会。answer pack() 行为不属于一条狗。包是一个不同的方面,将包传递给所有对象并要求对象加入包。(访问者模式/适配器模式)。我的 Wolf 班级可以使用相同的行为。
Am I rigid about this, no if it is only 1 off instance I am fine. If the answer is I am not sure, then you better play safe by working at interface contracts.
我对此是否严格,不,如果只有 1 次,我很好。如果答案是我不确定,那么您最好通过在接口合同中工作来确保安全。
回答by aperkins
For all the reasons stated by others, you shouldn't do this. However, if you cannot change the interface, the following is possible:
由于其他人陈述的所有原因,您不应该这样做。但是,如果您无法更改接口,则可能会出现以下情况:
for (BaseType element : list) {
SubType subType = (SubType)element;
...
}
As far as I know, this is the only way to do this and remain truly type safe - i.e. not rely on type erasure to catch any problems, which it will not necessarily do until much later.
据我所知,这是做到这一点并保持真正类型安全的唯一方法 - 即不依赖类型擦除来捕获任何问题,直到很久以后它才会这样做。
I realize this is not EXACTLY what you were looking for, but it does handle the casting.
我意识到这并不完全是您要找的东西,但它确实可以处理演员表。
回答by Alexander Pogrebnyak
If you are not partial to Google collections, you can wrap the list with transform
method. In your case it will be very efficient and totally compliant. I would put it as a wrapper method though as Brian has suggested.
如果你不偏爱谷歌收藏,你可以用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;
}
};
}
回答by Peter Centgraf
It is in fact possible to combine the cast with the for loop, like so:
实际上可以将强制转换与 for 循环结合起来,如下所示:
List<BaseType> list = DAO.getList();
for (SubType subType : ((List<SubType>) list)){
...
}
Or you can use this slightly-cleaner pattern:
或者你可以使用这个稍微干净的模式:
List<SubType> list = (List<SubType>) DAO.getList();
for (SubType subType : list){
...
}
You will get an unchecked cast warning from the Java compiler, unless you suppress it. The effect of the first form will be effectively identical to casting each element within the loop. The second form will also enforce that new additions to the list must conform to SubType.
您将收到来自 Java 编译器的未经检查的强制转换警告,除非您取消它。第一种形式的效果将与在循环中投射每个元素有效相同。第二种形式还将强制列表中的新增内容必须符合 SubType。
Note that this will NOT work with arrays, since arrays have distinct runtime types. In other words, BaseType[] is not castable to SubType[]. You can use the Arrays API to work around this, like so:
请注意,这不适用于数组,因为数组具有不同的运行时类型。换句话说,BaseType[] 不能转换为 SubType[]。您可以使用 Arrays API 来解决此问题,如下所示:
BaseType[] array = DAO.getArray();
for (SubType subType : Arrays.<SubType>asList(array)) {
...
}