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