泛型-定义Map <MyClassA <?>,MyClassB <?>>确保两者是相同的?

时间:2019-10-03 18:49:16

标签: java generics

我有一行代码:

private final Map<MyClassA<?>, MyClassB<?>> myMap = new HashMap<>();

有什么方法可以以告诉编译器?的方式定义该映射?在每种情况下都必须是同一班?

像这样吗?

private final <T> Map<MyClassA<T>, MyClassB<T>> myMap = new HashMap<>();

...这是不合法的语法吗?

这只是一个自学问题。

FWIW,我想添加一个方法

public <T> MyClassB<T> getForA(MyClassA<T> a) {
    return this.myMap.get(a);
}

但是除非我可以定义myMap来坚持要求键和值都包装相同的类型,否则我会遇到编译错误。

2 个答案:

答案 0 :(得分:1)

您已经知道,如果不同条目的键和值不同,则不能这样做:

map.put(new MyClassA<Foo>(), new MyClassB<Foo>());
map.put(new MyClassA<Bar>(), new MyClassB<Bar>());

(我从your comment处获得了此要求)

您可以做的是编写一些辅助方法,以强制执行此约束:

public <T> void put(MyClassA<T> key, MyClass<B> value) {
    // Maybe check at runtime if the constraint is not validated?
    map.put(key, value);
}

public <T> MyClassB<T> get(MyClassA<T> key) {
    // This will produce an unchecked warning.
    return (T) map.get(key);
}

只要您仅通过此类帮助方法访问地图(并且不使用原始类型),就不会违反地图上的约束,这使您可以编写类型安全的代码。

唯一不类型安全的部分是那些辅助方法,这是您必须要小心的地方。

答案 1 :(得分:0)

如果为所需的类型引入一个静态内部类,则可以执行类似的操作。例如:

public class DoubleGenericTest<T> {

   public static class MapHolder<Z> {
      private final Map<MyClassA<Z>, MyClassB<Z>> myMap = new HashMap<>();
   }

   private final MapHolder<String> stringMap = new MapHolder<>();
   private final MapHolder<Integer> integerMap = new MapHolder<>();


}

class MyClassA<X> {}
class MyClassB<Y> {}

这为您提供了将类型参数挂起的类。也许在每种情况下都不理想,但这是我唯一能想到的。