我正在尝试创建一个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<?> mySet[] = new EnumSet<?>[3];
这样做的原因是因为原始类型和无限通配符类型是统一的。因此,使用这种组件类型创建数组是类型安全的。
通过统一,我们的意思是类型信息在运行时可用。对于具体的参数化类型,情况并非如此,因为类型信息在类型擦除过程中会丢失。但是,对于原始类型,根本没有可以丢失的类型。<?>
类型也是如此。由于EnumSet<?>
是泛型类型EnumSet<T>
的所有实例化的超类型,所以在编译时没有关于EnumSet<?>
的特定类型信息,这些信息在运行时可能会丢失。
另一种选择是简单地创建一个列表。这比将数组与泛型类型混合要好得多:
List<EnumSet<MyEnum>> mySets = new ArrayList<>();
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));
}