1

我正在尝试创建一个 EnumSet 数组(使用 Eclipse)。

版本 1:

EnumSet mySet[] = new EnumSet[3];

这可行,但我收到警告:“EnumSet 是原始类型。对泛型类型 EnumSet 的引用应该被参数化”。

建议的版本 2:

EnumSet<MyEnum> mySet[] = new EnumSet[3];

再次警告:“类型安全:类型 EnumSet[] 的表达式需要未经检查的转换以符合 EnumSet[]”

建议的版本 3:

EnumSet<MyEnum> mySet[] = new EnumSet<MyEnum>[3];

现在我得到一个错误!“无法创建 EnumSet 的通用数组”

我应该怎么办?未参数化的 EnumSet 会有性能问题吗?

4

2 回答 2

2

您不能创建具体参数化类型的数组,因为它不是类型安全的。原因是,具体的参数化类型没有具体化,而数组是具体化的实体。

但是,您可以创建原始类型或无界通配符类型的数组:

EnumSet<?> mySet[] = new EnumSet<?>[3];

之所以可行,是因为原始类型和无界通配符类型已被具体化。因此,创建具有此类组件类型的数组是类型安全的。

通过具体化,我们的意思是类型信息在运行时可用。这不适用于具体的参数化类型,因为类型信息在类型擦除过程中会丢失。但是,对于原始类型,根本没有可以丢失的类型。类型也是如此<?>。由于EnumSet<?>是泛型类型的所有实例化的超类型EnumSet<T>,因此在编译时没有特定的类型信息EnumSet<?>会在运行时丢失。

另一种选择是简单地创建一个列表。这比将数组与泛型类型混合要好得多:

List<EnumSet<MyEnum>> mySets = new ArrayList<>();
于 2013-09-26T18:10:17.037 回答
0

Rohit Jain 的回答是正确的,只是我想添加扩展示例。它使用强制转换进行初始化。

定义:

public enum CellState {
  MINE_EMPTY,MINE_NEAR_1,MINE_NEAR_2,MINE_NEAR_3,MINE_NEAR_4,MINE_NEAR_5,MINE_NEAR_6,
  MINE_NEAR_7, MINE_NEAR_8,MINE,CLICK_OPEN, CLICK_MARK;

  public static EnumSet<CellState> ALL_OPTS = EnumSet.allOf(CellState.class);
  public static EnumSet<CellState> NOT_MINE = EnumSet.of(MINE_EMPTY,MINE_NEAR_1,MINE_NEAR_2,MINE_NEAR_3,MINE_NEAR_4,MINE_NEAR_5,MINE_NEAR_6,
        MINE_NEAR_7, MINE_NEAR_8); 
}

}

宣言:

  public EnumSet<CellState>[][] minefield; // 2-dimensional array

初始化(需要强制转换):

minefield = (EnumSet<CellState>[][]) new EnumSet<?>[width][height];
for (int y = 0; y < height; y++) {
  for (int x = 0; x < width; x++) {
    minefield[x][y] = EnumSet.allOf(CellState.class);
  }
}

用法:

if (!minefield[x][y].contains(CellState.MINE)) {
      minefield[x][y].add(minesNear(x, y));
}
于 2019-07-04T10:49:53.080 回答