我需要创建一个静态映射,该映射存储一些依赖于类类型作为键的实现。下面的代码片段中出现了一些类型兼容性问题。我花了很长时间解决这个问题,但没有成功。
// interface and classes to bound keys within Map
public interface IKey { ... }
public class Key1 extends IKey { ... }
public class Key2 extends IKey { ... }
// interface and classes to bound values within map
public interface IValue { ... }
public class Value1 implements IValue { ... }
public class Value2 implements IValue { ... }
public class Container {
public static Map<Class<? extends IKey>, Function<? extends Set<? extends IValue>, Integer> funcs = new HashMap<>();
static {
funcs.put(Key1.class, Container::method1);
funcs.put(Key2.class, Container::method2);
}
public static int method1(Set<Value1> s) {
return 1;
}
public static int method2(Set<Value1> s) {
return 2;
}
}
问题描述:
Incompatible types: Set<? capture of IValue> is not convertible to Set<Value1>
我真的很困惑,因为当我更改Map定义时它正在工作,但是我无法绑定Set:(
public static Map<Class<? extends IKey>, Function<Set, Integer> funcs = new HashMap<>();
我也注意到,下面的代码是正确的(在静态块中)
Function<Set<Value1>, Integer> m1 = Container::method1;
Function<Set<Value1>, Integer> m2 = Container::method2;
List<Function<? extends Set<? extends IValue>, Integer>> l1 = Arrays.asList(m1, m2);
//adding new element is not working
l1.add(Container::method1);
期望您能期望我的方法不正确,以及如何构建类似的结构:)
感谢帮助
修改
Set<IValue>
包含任何对象实现IValue
,因此同时添加Value1
和Value2
实例以进行设置是正确的。
Set<? extends IValue
可以采用两种形式:Set<Value1>
或Set<Value2>
。因此,Set<? extends IValue>
的变量可以通过分配它们之一来初始化,无法添加新的值进行设置(类型未知)
Set<? extends <Set<? extends IValue>>>
外部集可以同时包含Set<Value1>
和Set<Value2>
,但也不能更改。
就我而言:
public static Map<Class<? extends IKey>, Function<? extends Set<? extends IValue>, Integer>> funcs = new HashMap<>();
应该正常工作。更改静态块时确实如此:
static {
Function<Set<Value1>, Integer> m = Container::method1;
funcs.put(Key1.class, m);
}
我不知道为什么。也许方法引用上下文中有任何内部机制?