Java泛型:映射上的put()<;字符串,捕获#3-of?扩展抽象类>;不适用于参数(字符串、抽象类)

Java泛型:映射上的put()<;字符串,捕获#3-of?扩展抽象类>;不适用于参数(字符串、抽象类),java,generics,capture,Java,Generics,Capture,我正试图为从一个公共父类扩展而来的多个类实现一种内部工厂。大部分逻辑是相同的,但不能真正继承,因为查找需要是静态的。所需的语法类似于: Car c = AbstractClass.valueOf(Car.class, "Ford"); Car具有与cars相关的特定方法,但实例存储在公共缓存中。这是我到目前为止所拥有的。我的编译错误出现在构造函数中的put上: 类型映射中的方法put(String,capture#3-of?扩展了AbstractClass)不适用于参数(String,Abst

我正试图为从一个公共父类扩展而来的多个类实现一种内部工厂。大部分逻辑是相同的,但不能真正继承,因为查找需要是静态的。所需的语法类似于:

Car c = AbstractClass.valueOf(Car.class, "Ford");
Car具有与cars相关的特定方法,但实例存储在公共缓存中。这是我到目前为止所拥有的。我的编译错误出现在构造函数中的put上:

类型映射中的方法put(String,capture#3-of?扩展了AbstractClass)不适用于参数(String,AbstractClass)

import java.util.Collection;
导入java.util.HashMap;
导入java.util.LinkedHashMap;
导入java.util.Map;
导入java.util.Set;
导入java.util.TreeSet;
公共抽象类AbstractClass{

私有静态映射如果您只想存储任何抽象类,只需将您的映射声明为

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

private static Map根据
Object.getClass()
的javadoc,返回的类型是表达式的基于通配符的编译时类型。由于编译器只知道
this
返回一个抽象类实例,
this.getClass()
返回
类您的问题基本上可以归结为:

给定具有此签名的方法:

public static <T> void foo(T x, Class<T> y);
即使可以证明总是存在一些它是正确的
T
(即
T
=实际运行时类型的
bar

这是由于语言中的
.getClass()
类型的特殊情况导致了此问题

我可以想出两种方法来解决这个问题:

1) 强制转换要由与引用相同的类型参数化的类对象(尽管从技术上讲这不是真的):

AbstractClass(字符串名称){
AbstractClass.getNameMap((类)this.getClass()).put(名称,this);
}
2) 将对象强制转换为与类方法的参数相同的类型。由于类的类型中存在通配符,这将需要捕获帮助程序:

private static <T> void helper(Class<T> clazz, String name, Object obj) {
    AbstractClass.getNameMap(clazz).put(name, (T)obj);
}
AbstractClass(String name) {
    helper(this.getClass(), name, this);
}
private static void helper(类clazz、字符串名称、对象obj){
抽象类.getNameMap(clazz).put(name,(T)obj);
}
抽象类(字符串名){
helper(this.getClass(),name,this);
}

(如果您不想取消选中强制转换,可以执行
AbstractClass.getNameMap(clazz).put(name,clazz.cast(obj));

如果我这样做,则getNameMap()的返回类型不再是方法无法返回实际类型。它只能返回类型AbstractClass,该类型必须转换为适当的类型。它应该能够正常工作,以便您可以执行以下操作:Car Car=AbstractClass.valueOf(Car.class,“Ford”)。
public static <T> void foo(T x, Class<T> y);
<any reference type> bar;
foo(bar, bar.getClass()); // error
AbstractClass(String name) {
    AbstractClass.getNameMap((Class<AbstractClass>)this.getClass()).put(name, this);
}
private static <T> void helper(Class<T> clazz, String name, Object obj) {
    AbstractClass.getNameMap(clazz).put(name, (T)obj);
}
AbstractClass(String name) {
    helper(this.getClass(), name, this);
}