有 Java 编程相关的问题?

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

java泛型定义Map<MyClassA<?>,MyClassB<?>>确保两者?都一样吗?

我有一行代码:

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) 个答案

  1. # 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);
    }
    

    只要您仅通过此类帮助器方法访问映射(并且不使用原始类型),映射上的约束就不会被违反,这允许您编写类型安全代码

    唯一不安全的部分是那些helper方法,这是您必须小心的地方

  2. # 2 楼答案

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

    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> {}
    

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