gpt4 book ai didi

java - 迭代通配符列表并在其元素上调用方法(强制转换是否是糟糕的设计?)

转载 作者:行者123 更新时间:2023-12-02 01:16:53 25 4
gpt4 key购买 nike

我有一个List使用通配符如下:

List<DataLink<? extends Context>> dataLinks = new ArrayList<>();
dataLinks.add(new ContextDataLink());
dataLinks.add(new SomeOtherContextDataLink());

我希望能够迭代此 List并调用retrieve每个元素的方法:

Context context = new SomeOtherContext();

for(DataLink<? extends Context> dataLink : dataLinks) {
System.out.println(dataLink.retrieve(context));
}

但是,我在 println 中收到以下编译器错误声明:

The method retrieve(capture#3-of ? extends Context) in the type >DataLink<capture#3-of ? extends Context> is not applicable for the arguments >(Context)

有办法实现上述目标吗?它不一定必须使用泛型,但我觉得使用泛型可以让我防止显式转换

我浏览了一些关于 SO 的答案,并理解为什么会发生这个错误。但是,我无法找到解决方案来解决它。我知道我可以编写一个方法来捕获通配符,但这似乎也不能解决问题:

 public static <T extends Context> void retrieve(List<DataLink<T>> 
dataLinks,T context) {
for(DataLink<T> dataLink : dataLinks) {
dataLink.retrieve(context);
}
}

当我调用上面的检索方法时,出现以下编译错误:

The method retrieve(List<DataLink<T>>, T) in the type MyClass is not >applicable for the arguments >(List<DataLink<? extends Context>>, Context)

以下是 Context 的定义, SomeOtherContext , DataLink实现:

 static class Context {
public String doContextThings() {
return "contextThings";
}
}

static class SomeOtherContext extends Context {
public String doSomeOtherContextThings() {
return "someOtherContextThings";
}
}

interface DataLink<T extends Context> {
public String retrieve(T context);
}

static class ContextDataLink implements DataLink<Context> {

@Override
public String retrieve(Context context) {
return context.doContextThings();
}

}

static class SomeOtherContextDataLink implements
DataLink<SomeOtherContext> {

@Override
public String retrieve(SomeOtherContext context) {
return context.doSomeOtherContextThings();
}

}

注意:不涉及泛型的解决方案是最直接的解决方案,其中 DataLink类被修改为不采用类型参数并始终采用 Context作为 retrieve 的参数类型方法。在这里,子类将转换 Context无论他们期望什么类型。然而,问题仍然是一样的这被认为是糟糕的设计还是在这种情况下类型转换可以接受?

最佳答案

根本问题是你想给出 retrieve方法一个它不支持的参数。列表中的元素之一可能是 DataLink<ContextA> ,例如,您想调用 retrieve(ContextB)就在上面。

您需要编写一些代码来确定如何处理它。

如果您将该代码放入 retrieve方法实现,然后您可以将任何类型的上下文传递给任何 retrieve方法,您可以将其声明为简单的 Context范围。每个实现都可以执行 instanceof检查您传递给它的上下文并决定如何处理它。

DataLink 上的类型参数那么类就不需要定义 retrieve方法,但您仍然可以将其包含在类中,并根据需要将其用于其他用途。

关于java - 迭代通配符列表并在其元素上调用方法(强制转换是否是糟糕的设计?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58428995/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com