在HashMap中使用嵌套泛型类型

Pri*_*riv 0 java generics dictionary hashmap

我正在寻找一种方法,在Map类型中使用泛型Map类型,然后使用键和正确类型检索那些类型.例如:

private final <T> Map<A<T>,B<T>> map = new HashMap<>();

public <T> B<T> getB(final A<T> a) {
  return map.get(a);
}
Run Code Online (Sandbox Code Playgroud)

使用它的一个例子是:

final A<String> a = ...;
final B<String> b = getB(a);
Run Code Online (Sandbox Code Playgroud)

这是以任何方式存在还是有任何解决方法?

编辑:我知道我可以通过铸造东西解决它,但我想知道是否有一种更优雅的方式,不需要我投射我所追溯的每一个价值.

And*_*ner 6

您无法以这种方式声明地图.基本上,Java没有足够表达的类型系统.

但幸运的是,语言提供了从使用类型系统,在形式的逃生舱口石膏.基本上,强制转换是一种提供编译器没有的类型信息的方法; 然而,责任在于你,以确保它实际上类型安全的.

首先,使用通配符类型声明地图:

private final Map<A<?>,B<?>> map;
Run Code Online (Sandbox Code Playgroud)

然后,只放键/值对到其中的地图满足约束条件:

<T> void put (A<T> key, B<T> value) {
  map.put(key, value);
}
Run Code Online (Sandbox Code Playgroud)

然后当你再次获得元素时施放:

@SuppressWarnings("unchecked") // Safe
<T> B<T> get(A<T> key) {
  return (B<T>) map.get(key);
}
Run Code Online (Sandbox Code Playgroud)

关键是你可以比编译器更多地了解类型.如果您只注意安装可安全浇注的对,则可以安全地进行铸造.(您还需要确保equals方法将类型考虑在内,因此除非A<T>等于否).A<S>S == T

这基本上是"类型安全的异构容器",如Effective Java(第3版中的第33项)中所述.

我想知道是否有一种更优雅的方式,不需要我投出我所追溯的每一个价值.

首先,你实际上并没有get在运行时对方法进行强制转换:这就是未经检查的强制转换意味着什么.

另一方面,泛型引入了大量的强制转换 - 基本上泛型只是一种避免手动插入强制转换的方法.因此,如果演员表存在问题(例如表演),你已经在很多地方都观察到了这一点.

用Kubrick的话说:不要担心,并且喜欢演员.