Java 泛型 - 使用上限和下限通配符进行迭代

标签 java generics

我有2 个接口(interface):

public interface Flash { public void flash(int level); }

public interface SuperFlash extends Flash { public void flash(int level, boolean repeat); }

然后我有一个自定义集合类,它应该包含任意数量的实现 Flash 的东西或SuperFlash类声明看起来像

public class FlashyThings<? extends Flash>

因此该类可以保存 Flash 类型的实例及其子类型。

类内FlashyThings ,我正在使用 ArrayList 容纳所有这些对象:

private ArrayList<? extends Flash> things;

到目前为止一切顺利,现在,当我尝试迭代集合时,有没有一种方法可以在不使用 instanceof 的情况下了解/推断对象的动态类型(如下一个片段所示)?

for (Flash f : this.things) {
    if (f instanceof SuperFlash) { // <-- :(
        // SuperFlash things
    } else {
        // Flash things
    }
}  

这是奖牌的上界,现在是下界

首先,我必须将类声明更改为

public class FlashyThings

因为类声明中不允许使用下限通配符。 ArrayList 声明现在看起来像:

private ArrayList<? super SuperFlash> things;

现在迭代集合变为:

for (Object o : this.things) { // <-- :((
    // All things are of type Object which is *really* not cool
    if (o instanceof SuperFlash) { // <-- :(
        // SuperFlash things
    } else {
        // Flash things
    }
}

所以我几乎陷入了困境。

迭代此类构造的推荐方法是什么?总而言之,我想要实现的是

  • 最顶层描述的界面层次结构
  • 类(class) FlashyThings可参数化
  • 迭代ArrayList things ,考虑到其内容的动态类型(无需执行 instanceof 检查)

最佳答案

您需要做的是创建一个抽象的 FlashyThing,它在抽象类中执行尽可能多的共享方法,只将依赖于知道您拥有 Flash 或 SuperFlash 的内容留给子类。例如(为简洁起见,省略了公共(public)和私有(private)):

abstract class AbstractFlashyThing<F extends Flash> {

    List<F> flashes;

    AbstractFlashyThing() {
        flashes = new ArrayList<F>();
    }

    void doOperations() {
        for (F flash : flashes) {
            doOperation(flash);
        }
    }

    abstract void doOperation(F flash);

}

请注意泛型类型 F 如何尽可能用作占位符。

子类示例

class SuperFlashyThing extends AbstractFlashyThing<SuperFlash> {
    @Override
    void doOperation(SuperFlash superFlash) {
        // do super flash stuff
    }
}

子类是一个具体的实现,而不是泛型类,因此它的实例化如下。

SuperFlashyThing thing = new SuperFlashyThing();
// as opposed to the following
SuperFlashyThing<SuperFlash> thing = new SuperFlashyThing<SuperFlash>();

关于Java 泛型 - 使用上限和下限通配符进行迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25547205/

相关文章:

java - 我如何(或应该)将方面建议应用于动态代理?

java - 排除 Jhipster 并将 Spring Boot 从 1.4.0 升级到 2.0.3

Java:数据结构和通配符的泛型

c# - 有没有一种技术可以区分泛型类型的类行为?

c# - 对于 C#,是否可以在泛型类的实例声明中指定类型约束?

generics - Dart:不能将具有泛型的类型分配给类型变量

java - Android:将 VectorDrawable 添加到 ImageView

java - Android 中的 Toast 消息不可见\弹出

java - 可以通过Spring配置和启动嵌入式Tomcat吗?对 Jetty 好吗?

java - Java 中的通用静态方法