有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

以泛型类型作为键的Java泛型映射

我有以下地图。这两个映射都将ClassA/ClassB的实例和CellProcessor的实例作为值

Map<ClassA, CellProcessor> classAProcessors;
Map<ClassB, CellProcessor> classBProcessors;

我想创建一个映射,将上面的映射存储为值,并将key作为ClassA/ClassB的类类型,这样当我执行map.get(ClassA.class)时,它会返回我Map<ClassA, CellProcessor> classAProcessors

我写这个方法是为了创建最终的地图,但它似乎不起作用

public static <T> Map<Class<T>, Map<T, CellProcessor>> getOutputProcessors(){
    Map<ClassA, CellProcessor> classAProcessors = getOutputCellProcessorsForClassA();
    Map<Class<T>, Map<T, CellProcessor>> processors = Maps.newLinkedHashMap();
    processors.put(ClassA.class, classAProcessors ); //error here
    return processors;
}

编译器错误:

The method put(Class<T>, Map<T,CellProcessor>) in the type Map<Class<T>,Map<T,CellProcessor>> is not applicable for the arguments (Class<ClassA>, Map<ClassA,CellProcessor>)

有人能帮我理解这里出了什么问题吗

谢谢


共 (2) 个答案

  1. # 1 楼答案

    编译器报告了一个错误,因为您试图向映射processors添加一个类型不兼容的条目。在编译时,编译器不知道T的类型。类型T将由使用方法getOutputProcessors的客户端确定。方法processors.put要求第一个参数恰好是Class<T>的类型(T将仅由使用方法getOutputProcessors的代码确定),但您总是传递相同的ClassA.class值。方法processors.put的第二个参数也不正确,它应该恰好是Map<T, CellProcessor>的类型,并且您正在传递类型为Map<ClassA, CellProcessor>的永久参数。将类型T视为独立类型,因此在方法的代码中T并不等同于ClassA。方法的正确版本应如下所示:

    public static <T> Map<Class<T>, Map<T, CellProcessor>> getOutputProcessors(Class<T> key, Map<T, CellProcessor> classProcessors) {
        Map<Class<T>, Map<T, CellProcessor>> processors = new HashMap<Class<T>, Map<T, CellProcessor>>();
        processors.put(key, classProcessors);
        return processors;
    }
    

    可以通过以下方式使用此方法:

    Map<Class<ClassA>, Map<ClassA, CellProcessor>> processorsA = getOutputProcessors(ClassA.class, classAProcessors);
    Map<Class<ClassB>, Map<ClassB, CellProcessor>> processorsB = getOutputProcessors(ClassB.class, classBProcessors);
    

    但是通过这种方式,映射processorsAprocessorsB不兼容,您将无法将它们合并到一个映射中。因此,您需要使用不同于Map<Class<T>, Map<T, CellProcessor>>的映射类型
    最好的方法是为ClassAClassB创建一个超类型(如果它已经存在,则不创建超类型)(例如一个名为ClassBase的类或接口)^使用超类getOutputProcessors的{}方法如下所示:

    public static Map<Class<? extends ClassBase>, Map<? extends ClassBase, CellProcessor>> getOutputProcessors() {
        Map<Class<? extends ClassBase>, Map<? extends ClassBase, CellProcessor>> processors = 
                new HashMap<Class<? extends ClassBase>, Map<? extends ClassBase, CellProcessor>>();
    
        processors.put(ClassA.class, getOutputCellProcessorsForClassA());
        processors.put(ClassB.class, getOutputCellProcessorsForClassB());
    
        return processors;
    }
    

    如果出于某种原因,您的代码中不能包含超类类,那么您可以使用如下所示的方法:

    public static Map<Class<? extends Object>, Map<? extends Object, CellProcessor>> getOutputProcessors3() {
        Map<Class<? extends Object>, Map<? extends Object, CellProcessor>> processors = 
                new HashMap<Class<? extends Object>, Map<? extends Object, CellProcessor>>();
    
        processors.put(ClassA.class, getOutputCellProcessorsForClassA());
        processors.put(ClassB.class, getOutputCellProcessorsForClassB());
    
        return processors;
    }
    

    我希望我的回答能帮助你

  2. # 2 楼答案

    你为什么要加<T>,上课就够了

    如果你想使用<T>,把它改成并让ClassA和ClassB扩展基类