gpt4 book ai didi

java - 从 GenericType.class 过滤器获取最通用类型的集合

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:02:28 24 4
gpt4 key购买 nike

我提前为糟糕的标题道歉,热切接受改进建议。

假设我有一个方法可以过滤 List<T>基于 class 的任意类型, 返回一个新的 List其元素是作为给定类实例的输入列表的元素。这是一个简单的实现(是的,您也可以在带有流的 1-liner 中实现):

public static <T> List<T> filterByClass(List<?> list, Class<T> clazz) {
List<T> filtered = new ArrayList<>();
for (Object o : list) {
if (clazz.isInstance(o)) {
filtered.add(clazz.cast(o));
}
}
return filtered;
}

如果你向它传递一个非泛型类型的列表,比如 String,这会很好用如(打印 foo bar ):

List<Object> l = Arrays.<Object>asList(1, "foo ", 2, "bar ");
filterByClass(l, String.class).stream().forEach(System.out::println);

现在我想传递给通用类型的类进行过滤,比如 Optional<T> :

List<Object> l = Arrays.<Object>asList(1, Optional.of("foo"), 2, Optional.of("bar"));
filterByClass(l, Optional.class).stream().forEach(System.out::println);

工作正常并打印:

Optional[foo]
Optional[bar]

问题是那里隐藏了一个原始类型。 filterByClass 的返回类型上面的电话是List<Optional> , 不是 List<Optional<...>> .许多用途会触发有关原始类型等的警告。

现在我了解类型删除,我知道 class对象永远不会 carry generic type information - 没有这样的Optional<String>.classOptional<Integer>.class - 只有 Optional.class .

但是,仍然有比原始类型更好的返回值:我想要完全通用的通配符版本:List<Optional<?>> .这应该是完全类型安全的,因为任何 Optional是一个 Optional<?> ,对吧?

赋值无效,因为 List<Optional>不可转换为 List<Optional<?>>

List<Optional<?>> r = filterByClass(l, Optional.class);  

转换也不起作用,因为类型甚至不可转换(就像 Foo<T> 永远不能直接转换为 Foo<U>,无论不同类型 TU 之间的关系如何) ).

唯一的解决方案似乎是一直向下转换为原始 List然后返回到带有通配符参数化类型参数的列表:

List<Optional<?>> r = (List)filterByClass(l, Optional.class);  

现在显然这样的转换在一般情况下是不安全的,如果赋值中的类型参数 Optional<?> 这将是完全不安全的与 class 不匹配对象传递给 filterByClass - 虽然I think they are safe in the specific case that the class matches the type parameter with unbounded wildcards .

有没有办法在没有潜在不安全转换的情况下做到这一点,要么通过更改 filterByClass方法或结果的一些安全类型转换?

另一个可能的答案是这是不安全的(即 filterByClass(..., Optional.class) 的结果不能安全地转换为 List<Optional<?>> ,所以问题的格式不正确。

最佳答案

您可以更改 filterByClass 的签名到:

public static <T> List<T> filterByClass(List<?> list, Class<? extends T> clazz) {...}

然后你可以有T从受让人推断:

List<Object> l = Arrays.<Object>asList(1, Optional.of("foo"), 2, Optional.of("bar"));
List<Optional<?>> result = filterByClass(l, Optional.class);

这是因为原始 Optional可分配给 Optional<?> (这是安全的),所以 Class<Optional>满足Class<? extends Optional<?>> , 你可以添加 Optionalcast 返回到 Optional<?> 的列表.

关于java - 从 GenericType<T>.class 过滤器获取最通用类型的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47661471/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com