gpt4 book ai didi

Java 泛型 : put() on Map 不适用于参数 (String, AbstractClass)

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:54:33 26 4
gpt4 key购买 nike

我正在尝试为从公共(public)父级扩展的多个类实现一种实习生工厂。许多逻辑是相同的,但它不能真正被继承,因为查找需要是静态的。所需的语法类似于:

Car c = AbstractClass.valueOf(Car.class, "Ford");

Car 具有与汽车相关的特定方法,但实例存储在公共(public)缓存中。这是我到目前为止所拥有的。我的编译错误在构造函数中:

“类型 Map 中的方法 put(String, capture#3-of ? extends AbstractClass) 不适用于参数 (String, AbstractClass)”

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public abstract class AbstractClass {

private static Map<Class<? extends AbstractClass>, LinkedHashMap<String, ? extends AbstractClass>> map = new HashMap<Class<? extends AbstractClass>, LinkedHashMap<String, ? extends AbstractClass>>();

private static synchronized <T extends AbstractClass> Map<String, T> getNameMap(Class<T> clazz) {
LinkedHashMap<String, T> nameToEnum = (LinkedHashMap<String, T>) map.get(clazz);
if (nameToEnum == null) {
nameToEnum = new LinkedHashMap<String, T>();
map.put(clazz, nameToEnum);
}

return nameToEnum;
}

public static <T extends AbstractClass> T valueOf(Class<T> clazz, String name) {
return getNameMap(clazz).get(name);
}

public static <T extends AbstractClass> Collection<T> VALUES(Class<T> clazz) {
return getNameMap(clazz).values();
}

public static <T extends AbstractClass> Set<T> SORTED_VALUES(Class<T> clazz) {
return new TreeSet<T>(getNameMap(clazz).values());
}

AbstractClass(String name) {
AbstractClass.getNameMap(this.getClass()).put(name, this);
}

}

最佳答案

根据 Object.getClass() 的 javadoc ,返回的类型是表达式的基于通配符的编译时类型。因为编译器只知道 this返回一个 AbstractClass 实例,this.getClass()返回 Class<? extends AbstractClass> .

这意味着您调用 getNameMap在构造函数中将返回一个 Map<String, ? extends AbstractClass> .这意味着,虽然返回的 Map 具有特定(非通配符)类型的值,但在编译时不知道该确切类型;编译器只知道 Map 的值必须是 AbstractClass 或继承自 AbstractClass 的值。所以编译器不能安全地添加 this作为一个值,因为在编译时不知道 AbstractClass 的哪个子类型 this代表。

使用一个更简单的例子:如果一个方法返回 Map<String, ? extends Number>那么编译器将不知道将整数添加到 Map 是否安全,因为 Map 的实际非通配符类型可能是 Map<String, Double> , Map<String, Short>

至于解决方案:我不认为有一种方法可以让 Map 使用泛型将每个单独的键的类型与其对应的值的类型相匹配。我会忘记在内部 map 的值上使用有界类型,而是使用动态转换:

private static Map<Class<? extends AbstractClass>, Map<String, AbstractClass>> map = new HashMap<>();

private static synchronized Map<Class<? extends AbstractClass>, Map<String, AbstractClass>> getNameMap(Class<T> clazz) {
// same as before
}

public static <T extends AbstractClass> T valueOf(Class<T> clazz, String name) {
return clazz.cast(getNameMap(clazz).get(name));
}

关于Java 泛型 : put() on Map<String, 捕获#3-of ? extends AbstractClass> 不适用于参数 (String, AbstractClass),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13788294/

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