3

我第一次使用 EnumMap,不明白参数传递实际上在做什么。据我所知,它只是“K.class”,其中 K 是映射键。这工作得很好,但我在 Java 的其他任何地方都没有看到过,而且我不清楚它在构造中实际扮演什么角色。

我想这是一个理论上的问题,因为代码运行:“K.class”参数是什么意思,EnumMap 需要它做什么?

4

2 回答 2

8

请参阅类文字的链接问题。

EnumMap特别需要它,因为它需要知道枚举有多少不同的值。这是因为 EnumMap 是一种高度优化的枚举映射实现,它只使用一个数组,每个可能的值都有一个插槽(而不是像 HashMap 这样的更大的数组)。当您调用 时get(),它会检索给定键的索引(即第一个枚举值、第二个等)并查找其内部数组的适当位置。为此,构造函数需要知道可能值的数量以分配正确大小的数组。给定类对象,它可以调用getEnumConstants()以找出此枚举的现有值的数量。

此外,想象以下代码:

enum Enum1 { V1, V2; }
enum Enum2 { W1, W2; }
EnumMap<Enum1, Object> map = new EnumMap<Enum1, Object>(Enum1.class);
map.put(Enum1.V1, new Object());
map.get(Enum2.W1);

现在该get方法显然应该返回null。但是,正如我所说,映射内部只有一个数组,在这种情况下大小为 2,新对象在第一个插槽中,而在第二个插槽中为 null。当您将 Enum1.V1 传递给put(). 但是,该方法get现在需要知道传递的值不属于正确的枚举,因此映射中的该键没有值。这里也需要正确枚举的类型,为此您需要将类型传递给构造函数。

如果您不向构造函数提供有关枚举的一些信息,它就不会知道您打算将哪个枚举用于此地图实例。即使您编写 new ,由于类型擦除EnumMap<MyEnum, SomeValue>(),构造函数也无法知道泛型类型参数的值。MyEnum因此需要有另一种方式将信息传递给构造函数。

于 2014-02-28T20:01:52.617 回答
2

基于 的来源EnumMap: 看来,当您构造 时EnumMap,它所做的第一件事就是分配一个数组,该数组对于enum类中的每个枚举常量都有一个元素。 EnumMap应该是有效的,所以它会分配一个固定的数组是有道理的。为此,它需要知道类。如果不是用于类型擦除,这可以通过查看第一个类型参数在K.class哪里来完成。不幸的是,Java 泛型的设计阻止了这一点。KEnumMap<K,V>

于 2014-02-28T20:03:11.840 回答