假设我想做以下事情:
public static <V> Set<V> setOf(V... elem)
{
Set<V> set = null;
if (elem[0] instanceof Enum)
set = Sets.newEnumSet(elem, elem[0].getClass()); OR
set = EnumSet.<V>noneOf(elem[0].getClass());
return set;
}
这些或其他几种变体似乎都不起作用。有人可以向我解释发生了什么事吗?我查看了How do I get the type object of a genericized Enum?和其他一些类似的问题,但我仍然无法使其发挥作用。
答案 0 :(得分:1)
首先,您需要确保类型V
被限制为枚举类型;您可以通过指定V
必须extends Enum<V>
。
然后,您需要提供枚举类型的Class
。由于类型擦除,您无法在运行时获取它。这是必需的,因为要构造一个新的空EnumSet
,您需要指定元素的类型。
最后,您有几种方法可以创建集合,但最简单的方法可能是使用Stream API:
@SafeVarargs
public static <V extends Enum<V>> Set<V> setOf(Class<V> enumClass, V... elem) {
return Arrays.stream(elem).collect(Collectors.toCollection(() -> EnumSet.noneOf(enumClass)));
}
请注意,如果您可以保证至少有1个元素,则可以使用EnumSet.copyOf(Arrays.asList(elem))
而无需传递该类。
答案 1 :(得分:0)
如果您无法将通用参数绑定到V extends Enum<V>
,则可以按如下方式编写可编译代码:
public <V> Set<V> setOf(V... elem) {
Set<V> set = null;
if (elem[0].getClass().isEnum()) {
set = (Set<V>) EnumSet.copyOf((Collection<Enum>)Arrays.asList(elem)) ;
}
return set;
}
当然有不安全的演员警告。
我还将类型检查更改为:
if (elem[0].getClass().isEnum())
恕我直言的更清洁。