gpt4 book ai didi

java - 泛型通配符不接受实现接口(interface)的类

转载 作者:行者123 更新时间:2023-12-01 13:37:27 25 4
gpt4 key购买 nike

我想要一个以类类型作为键的映射,以避免在访问值时进行强制转换。

更新
以下是您可以在 IDEA 中复制/粘贴并重现它的实际代码。

    interface MyInterface {

}

class SomeConcreteClass implements MyInterface{

}

private Map<Class<?>, ? extends MyInterface> map = newMap();

private Map<Class<?>, ? extends MyInterface> newMap() {
Map<Class<?>, ? extends MyInterface> map = new HashMap<>();
map.put(SomeConcreteClass.class, new SomeConcreteClass());
return map;
}

private void accessMap() {
SomeConcreteClass clazz = (SomeConcreteClass) map.get(SomeConcreteClass.class); <== I want to avoid cast here
}

问题:这不能编译。我进入这一行:
map.put(SomeConcreteClass.class, new SomeConcreteClass());  

错误:

Wrong 2nd argument type. Found: 'SomeConcreteClass required '? extends MyInterface`



我在这里做错了什么? SomeConcreteClass应该被接受,因为它实现了接口(interface)

最佳答案

这可以简化很多:

Map<String, ? extends CharSequence> map = new HashMap<>();
map.put("", ""); // <-- will not compile

List<? extends CharSequence> l = new ArrayList<>();
l.add(""); // <-- will not compile

这背后的原理叫做 PECS (非常有名)。为什么不允许这样读起来有点冗长,但主要解释了 here .虽然不明显,但如果允许这样做 - 它可能会在其他地方引起问题,我链接的答案解释了这一点。

您可以使用所谓的 typesafe heterogeneous container 来实现您想要的。 :
static class TypeSafeValue {

private MyInterface t;

TypeSafeValue() {
}

public <T> TypeSafeValue setValue(MyInterface t) {
this.t = t;
return this;
}

public <T> T getValue(Class<T> clazz) {
return clazz.cast(t);
}
}

用法是:
private Map<Class<?>, TypeSafeValue> newMap() {
Map<Class<?>, TypeSafeValue> map = new HashMap<>();
map.put(SomeConcreteClass.class, new TypeSafeValue().setValue(new SomeConcreteClass()));
return map;
}

private void accessMap() {
SomeConcreteClass clazz = map.get(SomeConcreteClass.class).getValue(SomeConcreteClass.class);
}

关于java - 泛型通配符不接受实现接口(interface)的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61078299/

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