有 Java 编程相关的问题?

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

java如何捕获和传播通配符类型参数?

我有几个类具有相同的方法,除了某些参数类型:

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(); }
}

现在,我尝试使用一个主类来存储这些类对象的混合列表,并为每个实例在其两个方法之间传递信息:

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)));
        });
    }

List<ICls<?>>Map<String, ?>语句正常。但是,map.get(key)抛出一个IDE错误:

'doSomething(<String, capture<?>>) in '...ICls' cannot be applied to 'String, capture<?>'

将鼠标光标悬停在有问题的语句上会显示:

Required type: capture of ?
Provided: capture of ?

假设我不能/不想将泛型类型T更改为Object,并且也不想更改体系结构,那么我该如何使这里的代码编译

我已尝试更改doSomething的签名,以便它接受整个Map<String, T>并像这样调用它,但也没有运气:

cls.doSomething(cls.getSomething());

共 (1) 个答案

  1. # 1 楼答案

    这为我汇编了:

    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)));
            }
        }
    }
    

    它明确了地图和cls之间的关系

    在原始上下文中,因为列表的类型是ICls<&燃气轮机;我们不能得到这种关系,但是一旦我们得到一个ICL,我们就可以引入一个类型变量T,它允许我们表达getSomethingdoSomething之间的关系