在Java中创建EnumSet数组

时间:2013-09-26 18:06:46

标签: java enumset

我正在尝试创建一个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会出现性能问题吗?

2 个答案:

答案 0 :(得分:2)

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

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

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

这是有效的原因是因为原型和无界通配符类型是有效的。因此,创建具有此类组件类型的数组是类型安全的。

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

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

List<EnumSet<MyEnum>> mySets = new ArrayList<>();

答案 1 :(得分: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));
}