钻石操作员; 初始化paremeterized通用类

dog*_*ose 5 java generics collections initialization

通常需要快速收集值才能迭代它.而不是手动创建实例,添加项目或执行众所周知的构造函数初始化,从数组(Set<String> mySet = new HashSet<String>(Arrays.AsList("a", "b", "c")))创建列表集合我想创建一个应该为我做的工作的函数.

除了Fact之外,我想提供<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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这非常有效,可以像以下一样使用:

LinkedList<String> myList = StaticHelper.initializeCollection(LinkedList.class, "a", "b");
Run Code Online (Sandbox Code Playgroud)

要么

HashSet<Integer> mySet = StaticHelper.initializeCollection(HashSet.class, 1,2,3,4,5);
Run Code Online (Sandbox Code Playgroud)

从我现在测试的,这按预期工作.唯一的问题是验证器声明,正在进行未保存的类型转换.验证器说,使用Set的例子

 Type safety: The expression of type HashSet needs unchecked conversion to conform to HashSet<Integer>
Run Code Online (Sandbox Code Playgroud)

当我仔细查看返回值时,IDE正在声明我的函数,它看起来像这样:

 <HashSet, Integer> HashSet my.namespace.helper.CollectionHelper.initializeCollection(Class<HashSet> concreteClass, Integer... objects)
Run Code Online (Sandbox Code Playgroud)

因此,验证OFC认为,他必须从做取消保存投HashSetHashSet<Integer>.

但在我看来,函数的返回值是T,几乎定义为Collection<S>- 而不是Collection.

现在我想知道是否:

  • 我的功能存在一个问题,实际上是一个无法解决的类型转换
  • IDE存在一个问题,没有显示正确的returnValue,因此验证器无法正常工作.

Sidenode: 即使已经发布了一个好的替代品(我已经在使用),我对这个问题的解决方案很感兴趣.

public static <T extends Collection<S>, S> T<S> initializeCollection ...
Run Code Online (Sandbox Code Playgroud)

或使用

... initializeCollection(HashSet<Integer>.class,...
Run Code Online (Sandbox Code Playgroud)

显然是无效的语法,但基本上看起来像什么是必需的.

ass*_*ias 3

这并不是一个直接的答案,但你可以通过以下方式使其变得更简单:

@SafeVarargs
public static <T extends Collection<S>, S> T initializeCollection(T collection, S... objects) {
    Collections.addAll(collection, objects);
    return collection;
}
Run Code Online (Sandbox Code Playgroud)

并用以下方式调用它:

HashSet<Integer> mySet = initializeCollection(new HashSet<>(), 1, 2, 3, 4, 5);
Run Code Online (Sandbox Code Playgroud)