Java 从GenericType获取最通用类型的集合<;T>;。类过滤器

Java 从GenericType获取最通用类型的集合<;T>;。类过滤器,java,generics,Java,Generics,我为这个糟糕的标题提前道歉,我们热切地接受改进建议 假设我有一个方法,它根据类过滤任意类型的列表,返回一个新的列表,其元素是给定类实例的输入列表的元素。下面是一个简单的实现(是的,您也可以在带有流的单行程序中实现): 现在,我想在泛型类型的类上传递到filter,比如说Optional: 问题是那里隐藏着一个原始类型。上面的filterByClass调用的返回类型是List,而不是List。许多使用都会触发有关原始类型等的警告 现在我了解了类型擦除,我知道类对象永远不会-没有这样的可选。类或可选

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

假设我有一个方法,它根据
过滤任意类型的
列表
,返回一个新的
列表
,其元素是给定类实例的输入列表的元素。下面是一个简单的实现(是的,您也可以在带有流的单行程序中实现):

现在,我想在泛型类型的类上传递到filter,比如说
Optional

问题是那里隐藏着一个原始类型。上面的
filterByClass
调用的返回类型是
List
,而不是
List
。许多使用都会触发有关原始类型等的警告

现在我了解了类型擦除,我知道
对象永远不会-没有这样的
可选。类
可选。类
-只有
可选。类

但是,仍然有一个比原始类型更好的返回值:我希望使用完全通用的通配符版本:
List
,对吗


分配不起作用,因为
List
不能转换为
List您可以将
filterByClass
的签名更改为:

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

这是因为原始的<代码>可选的<代码>可分配给<代码>可选<代码>(这是安全的),所以<代码>类< /代码>满足<代码>类> <代码>,并且可以添加<代码>可选< <代码> >代码> >可选< <代码> >

在<代码>可选< <代码>的情况下,您是否考虑<代码>可选?
是否为
可选的
的实例?您可以向filter方法提供一个
函数
,如果它是实例,它将返回一个强制引用,或者返回null。在
可选
列表
等情况下,您必须找到一些方法来确定是否可以安全地进行铸造,例如
!opt.isPresent()| | opt.get()instanceof which
@AndyTurner-是的,我认为
可选。empty()
对于任何U来说都是
可选的
。不过关于你的建议,我对“查看”类型
T
不感兴趣:我只想得到一个
列表
(因此,原始类型
Foo
可以安全地设置为
Foo
)。我会接受在我的类型中有一个无界通配符。这就是诀窍!附加问题:如果我按照你的建议让
T
进行推断,这是可行的,但我一直认为这只是一个快捷方式,如果我想的话,我可以显式指定函数类型参数。但是如果我将你的最后一行更改为
List>filterByClass(l,Optional.class);
它无法编译(抱怨
Optional.class
class>
不匹配)。这是怎么回事?有什么类型参数可以使用,或者类型推断有什么“魔力”吗这里?注意
Class
是这个函数出现的类。嗯,我说,但是
javac
似乎并不真的喜欢它:顺便说一下,我使用/发布的两行测试代码只在eclipse中工作。添加
this
javac
与eclipse差异的显式类型提示非常有趣,我猜
 javac
就在这里,因为一些具有相同转换(没有参数或返回类型推断)的测试在eclipse上也会失败。一般来说,将
P1
转换为
P1>
似乎是不合法的,但我们希望一些语言律师类型能够参与进来加以确认。
List<Object> l = Arrays.<Object>asList(1, "foo ", 2, "bar ");
filterByClass(l, String.class).stream().forEach(System.out::println);
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]
List<Optional<?>> r = filterByClass(l, Optional.class);  
List<Optional<?>> r = (List)filterByClass(l, Optional.class);  
public static <T> List<T> filterByClass(List<?> list, Class<? extends T> clazz) {...}
List<Object> l = Arrays.<Object>asList(1, Optional.of("foo"), 2, Optional.of("bar"));
List<Optional<?>> result = filterByClass(l, Optional.class);