简体   繁体   English

Java:对于每个循环,迭代扩展对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM