【发布时间】:2014-02-05 11:33:19
【问题描述】:
通常需要快速收集一组值才能对其进行迭代。我不想手动创建实例、添加项目或执行众所周知的构造函数初始化,即从数组的列表中创建一个集合 (Set<String> mySet = new HashSet<String>(Arrays.AsList("a", "b", "c"))),我想创建一个应该为我完成这项工作的函数。
事实上,我想提供泛型参数<S> 以用于集合类,我还想提供泛型参数<T> - Collection 的实际类型。
所以,我的第一个方法是:
public static <T extends Collection<S>, S> T initializeCollection(Class<T> concreteClass, S... objects) {
T result;
try {
result = concreteClass.newInstance();
for (S s : objects) {
result.add(s);
}
return result;
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
这很好用,可以像这样使用:
LinkedList<String> myList = StaticHelper.initializeCollection(LinkedList.class, "a", "b");
或
HashSet<Integer> mySet = StaticHelper.initializeCollection(HashSet.class, 1,2,3,4,5);
从我现在测试的结果来看,这可以按预期工作。唯一的问题是验证器声明正在进行未保存的类型转换。使用 Set 的示例,验证器说
Type safety: The expression of type HashSet needs unchecked conversion to conform to HashSet<Integer>
当我仔细查看 IDE 为我的函数声明的返回值时,它看起来像这样:
<HashSet, Integer> HashSet my.namespace.helper.CollectionHelper.initializeCollection(Class<HashSet> concreteClass, Integer... objects)
因此验证者 ofc 认为,他必须执行从 HashSet 到 HashSet<Integer> 的未保存转换。
但在我看来,函数的返回值是T,它几乎被定义为Collection<S>——而不是Collection。
现在我想知道是否:
- 我的函数存在问题,真的发生了未保存的类型转换
- IDE 存在问题,未显示正确的 returnValue,因此验证器无法正常工作。
侧节点: 即使已经发布了一个好的替代方法(我已经在使用),我对这个问题的解决方案非常感兴趣。
public static <T extends Collection<S>, S> T<S> initializeCollection ...
或使用
... initializeCollection(HashSet<Integer>.class,...
显然是无效的语法,但基本上看起来像什么是必需的。
【问题讨论】:
-
我认为问题在于编译器无法从
.class文字中获取通用信息。因此,我认为在没有警告的情况下这样做是不可能的。
标签: java generics collections initialization