[英]How to capture and propagate a wildcard type argument?
I have a couple of classes having identical methods, except with respect to certain parameter types:我有几个具有相同方法的类,除了某些参数类型:
interface ICls<T> {
void doSomething(String key, T value);
Map<String, T> getSomething();
}
class ClsA implements ICls<Boolean> {
@Override public void doSomething(String key, Boolean value) { }
@Override public Map<String, Boolean> getSomething() { return Map.of(); }
}
class ClsB implements ICls<String> {
@Override public void doSomething(String key, String value) {}
@Override public Map<String, String> getSomething() { return Map.of(); }
}
Now I'm trying to have a main class that stores a mixed list of these class objects and for each of these instances, passes info between its two methods:现在我正在尝试拥有一个主要的 class 存储这些 class 对象的混合列表,并且对于这些实例中的每一个,在其两种方法之间传递信息:
class Main {
List<ICls<?>> list = List.of(
new ClsA(),
new ClsB()
);
void run() {
list.forEach(cls -> {
Map<String, ?> data = cls.getSomething();
data.keySet().forEach(key -> cls.doSomething(key, data.get(key)));
});
}
The List<ICls<?>>
and Map<String, ?>
statements are OK. List<ICls<?>>
和Map<String, ?>
语句都可以。 However, the map.get(key)
throws an IDE error:但是, map.get(key)
会引发 IDE 错误:
'doSomething(<String, capture<?>>) in '...ICls' cannot be applied to 'String, capture<?>'
Hovering the mouse cursor over the offending statement shows:将鼠标 cursor 悬停在违规语句上显示:
Required type: capture of ?
Provided: capture of ?
Assuming that I can't/don't want to change the generic type T
to Object
, and don't want to change the architecture either, what can I do to make the code here compile?假设我不能/不想将通用类型T
更改为Object
,并且也不想更改架构,我该怎么做才能使这里的代码编译?
I've tried changing the signature of doSomething
so that it accepts the entire Map<String, T>
and call it like so, with no luck either:我尝试更改doSomething
的签名,以便它接受整个Map<String, T>
并像这样调用它,但也没有运气:
cls.doSomething(cls.getSomething());
This compiles for me:这为我编译:
import java.util.List;
import java.util.Map;
public class Comparison {
interface ICls<T> {
void doSomething(String key, T value);
Map<String, T> getSomething();
}
static class ClsA implements ICls<Boolean> {
public void doSomething(String key, Boolean value) {}
public Map<String, Boolean> getSomething() { return null; }
}
static class ClsB implements ICls<String> {
public void doSomething(String key, String value) {}
public Map<String, String> getSomething() { return null; }
}
static class Main {
List<ICls<?>> list = List.of(
new ClsA(),
new ClsB()
);
void run() {
list.forEach(cls -> {
doIt(cls);
});
}
<T> void doIt(ICls<T> cls) {
Map<String, T> data = cls.getSomething();
data.keySet().forEach(key -> cls.doSomething(key, data.get(key)));
}
}
}
It makes clear the relationship between the map and the cls.它明确了 map 和 cls 之间的关系。
In the original context, because the type of the List is ICls<?> we can't get that relationship, but once we get a single ICls we can introduce a type variable T
which allows us to express the relationship between getSomething
and doSomething
.在原始上下文中,因为 List 的类型是 ICls<?> 我们无法得到这种关系,但是一旦我们得到一个 ICls,我们就可以引入一个类型变量T
,它允许我们表达getSomething
和doSomething
之间的关系。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.