Java通配符帮助类<;T>;列出<;类<;T>>;,可能的
我已经很长时间没有编码了,我已经失去了对通配符的控制 我有一个整洁的小功能,非常好用Java通配符帮助类<;T>;列出<;类<;T>>;,可能的,java,list,object,search,wildcard,Java,List,Object,Search,Wildcard,我已经很长时间没有编码了,我已经失去了对通配符的控制 我有一个整洁的小功能,非常好用 public static <T> ArrayList<T> GetObjects(List<?> list, Class<T> c){ ArrayList<T> objects = new ArrayList(); for(Object o : list){ if(c.isInstance(o)){
public static <T> ArrayList<T> GetObjects(List<?> list, Class<T> c){
ArrayList<T> objects = new ArrayList();
for(Object o : list){
if(c.isInstance(o)){
objects.add(c.cast(o));
}
}
return objects;
}
publicstaticarraylistgetobjects(列表,c类){
ArrayList对象=新的ArrayList();
用于(对象o:列表){
if(c.isInstance(o)){
添加(c.cast(o));
}
}
归还物品;
}
然而,我希望它能够接受一个类列表,并执行类似的操作
public static <T> ArrayList<T> GetMultipleObjects(List<?> list, List<Class<T>> classes){
ArrayList<T> objects = new ArrayList();
for(Object o : list){
for(Class c : classes){
if(c.isInstance(o)){
objects.add(c.cast(o));
}
}
}
return objects;
}
publicstaticarraylistgetmultipleobjects(列表,列表类){
ArrayList对象=新的ArrayList();
用于(对象o:列表){
用于(c类:类){
if(c.isInstance(o)){
添加(c.cast(o));
}
}
}
归还物品;
}
事后看来,这显然是不可能的 Louis的评论是正确的:在Java中没有合理的方法来定义这个函数 Java没有析取类型——也就是说,没有办法表达像“类型是
字符串
或整数
”这样的概念。最接近的方法是找到一个公共超类型——因为所有可实例化类型都继承自对象
(模原语,但现在让我们把它们放在一边),所以可以保证始终能够找到一个公共超类型,尽管它可能只是对象
,这通常不是很有用
为了说明为什么会出现这种情况,请思考此函数可以用于哪些类型的事情。我看到两种情况:
案例1:您希望筛选到一个类型是共享一个公共超类型的一个或多个类型的子类型,并返回该超类型的列表。通过将通配符类型与类型参数一起使用,您可以轻松做到这一点:
public static <T> List<T> filter(
List<?> input,
List<? extends Class<? extends T>> subtypesOfT) {
// implementation exactly as you have it
}
也就是说,即使您有这样一个函数,它也不会特别有用,因为您可以构建一个
列表
,但您无法静态地知道t
是什么(因为它是动态计算的),所以我也不认为这是你真正想要的。你对列表的期望是什么T
只有一个类。如果有多个类,您会怎么做?你只需要列出一张所有不同类型的列表,并定义“不起作用”。目前我怀疑的唯一问题是第行中的objects.add(c.cast(o))
因为c
是原始Class
而不是Class
所以cast
返回Object
而不是T
,这是ArrayList对象所期望的。我看到了我的问题,ArrayList。我将使用一个接口。@onlywar10ck93,不,不清楚。如果我传入Arrays.asList(Integer.class,String.class)
,我会得到什么?列表
?那有什么用呢?谢谢Daniel,我已经有一年多没有看过我的代码了。我意识到我在评论的中途是多么愚蠢。不过,感谢您的代码,这里有一些非常好的泛型类型使用示例。
private static Class<?> findCommonSupertype(List<Class<?>> types) {
Class<?> result = types.get(0);
for (Class<?> type : types) {
// Keep going as long as result is a supertype of the current type.
if (result.isAssignableFrom(type)) {
continue;
}
// Skip interfaces since they unify with any class type (unless
// the class is final, which we don't check for here).
if (result.isInterface() && !type.isInterface()) {
result = type;
} else if (type.isInterface()) {
continue;
}
// Otherwise, scan up through the inheritance hierarchy to find a
// new type that can serve as a common supertype for type and result.
Class<?> supertype = type;
while (!supertype.isAssignableFrom(result)) {
supertype = supertype.getSuperclass();
if (supertype == null) {
throw new IllegalArgumentException(
type + " and " + result + " do not share a common supertype");
}
}
result = supertype;
}
return result;
}