[英]Java: For each loop , Iteration over extended objects
My Question might be very simple, 我的问题可能很简单,
I have a class Result
with some inner fields , setters and getters. 我有一个带有一些内部字段,setter和getter的类
Result
。
Additionally, i have class Special1Result
which extends Result
and includes several more fields and Special2Result
with some more data. 另外,我有一个类
Special1Result
,它扩展了Result
并包含了更多的字段和Special2Result
以及更多的数据。
In different class Dispatcher
, i have written the following method: 在不同的
Dispatcher
类中,我编写了以下方法:
processResults(List<? extends Result> results)
, which is only familiar with Result
(I need this method to query if there is specific field in the extended Result object - i am using annotations). processResults(List<? extends Result> results)
,它只熟悉Result
(我需要这个方法来查询扩展Result对象中是否有特定字段 - 我正在使用注释)。
So i have decided to use the extended for-each loop: for (Result res : results) {}
所以我决定使用扩展for-each循环:
for (Result res : results) {}
So what is my question ? 那么我的问题是什么? i am trying to find over the web how to write this for loop for extended objects, eg something like this
for (? extends Results res: results){}
我试图通过网络找到如何为扩展对象写这个for循环,例如这样的东西
for (? extends Results res: results){}
Is it possible? 可能吗? How is the correct way to write it?
写它的正确方法怎么样?
All you know about a List<? extends Result>
你对
List<? extends Result>
所有了解List<? extends Result>
List<? extends Result>
is that each element will be a Result
- so that's all you can put in the enhanced for loop syntax. List<? extends Result>
是每个元素都是一个Result
- 所以你可以放入增强的for循环语法。
If you need members which aren't declared in Result
, you'll need to cast inside the loop: 如果您需要未在
Result
声明的成员,则需要在循环内部进行强制转换:
for (Result result : results) {
if (result instanceof CleverResult) {
CleverResult clever = (CleverResult) result;
// Use clever here
}
}
Think about what you'd write if you weren't using an enhanced for loop - you'd still need to write the cast, wouldn't you? 想想如果你没有使用增强的for循环你会写什么 - 你还需要写演员,不是吗?
Of course, if you know that the list should really only contain one specific type, you can always cast unconditionally in the loop. 当然,如果您知道列表实际上只包含一个特定类型,则始终可以无条件地在循环中进行转换。
I am trying to find over the web how to write this for loop for extended objects, eg something like this
我试图通过网络找到如何为扩展对象编写这个for循环,例如像这样的东西
for (? extends Results res: results){}
No, this is not possible: you cannot statically type items supplied dynamically at run-time. 不,这是不可能的:您无法静态键入在运行时动态提供的项目。
How is the correct way to write it?
写它的正确方法怎么样?
You are already doing it: 你已经这样做了:
for (Results res: results) {
}
If you would like to test for Special2Result
inside that loop, you can do it, but usually it tells that your design can be improved. 如果您想在该循环中测试
Special2Result
,您可以这样做,但通常它会告诉您的设计可以改进。 A better alternative is to use a mechanism of double dispatch, such as the Visitor Pattern , to hide the details of special treatment for your subclasses. 更好的选择是使用双重调度机制(例如访问者模式 )来隐藏子类的特殊处理细节。
Java has type erasure - the concrete type parameters of collections are not present at runtime. Java具有类型擦除 - 集合的具体类型参数在运行时不存在。
So if you have a List, the java compiler will ensure that no code will put anything into the list that isnt a subclass of Result. 因此,如果您有一个List,那么java编译器将确保没有代码将任何内容放入不属于Result子类的列表中。
Accordingly, at runtime, all your loop can know is that the contents are all subclasses of Result - so the only way to loop over them is as a set of references to Result, with whatever polymorphic behaviour that is present as a result of any subclasses that are in the list. 因此,在运行时,您的所有循环都可以知道内容是Result的所有子类 - 因此循环它们的唯一方法是作为Result的一组引用,具有任何子类的结果所呈现的任何多态行为在列表中。
Since your concrete sublasses only differs by nature of fields, I would suggest you to benefit from simple polymorphism. 由于您的具体子类仅因字段的性质而不同,我建议您从简单的多态性中受益。
You would end up with a Result
interface/abstract class defining an execute()
method class implemented by as many classes or subclasses as you need containing themselves action to do. 您最终将得到一个
Result
接口/抽象类,它定义一个execute()
方法类,该类由您需要包含自己要执行的操作的多个类或子类实现。
Therefore, your client code could merely use: 因此,您的客户端代码只能使用:
for (Result res : results){ //results being as a List<Result> type
res.execute();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.