在Java中,为什么只能使用泛型限制集合参数?
下面我有两个通用方法。两者都有两个参数化类型T和V扩展T。第一个方法foo接受类型T和V的参数。奇怪的是,我可以调用foo(“hello”,new Integer(10)),它编译并运行,即使Integer显然不扩展字符串。第二个方法bar采用List在Java中,为什么只能使用泛型限制集合参数?,java,generics,methods,Java,Generics,Methods,下面我有两个通用方法。两者都有两个参数化类型T和V扩展T。第一个方法foo接受类型T和V的参数。奇怪的是,我可以调用foo(“hello”,new Integer(10)),它编译并运行,即使Integer显然不扩展字符串。第二个方法bar采用List和List类型的参数。在这里,我不能调用bar,向它传递字符串列表和整数列表。为什么后者限制类型,而前者不限制类型 public class GenMeth { public static void main(String[] args)
public class GenMeth {
public static void main(String[] args) {
List<String> s_list = new ArrayList<>();
s_list.add("hello");
List<Integer> i_list = new ArrayList<>();
i_list.add(10);
foo("hello", new Integer(10)); // will compile - why?
bar(s_list, i_list); // won't compile - understandable
}
public static <T,V extends T> void foo(T obj1, V obj2) {
// do something
}
public static <T,V extends T> void bar(List<T> list1, List<V> list2) {
// do something
}
}
公共类GenMeth{
公共静态void main(字符串[]args){
List s_List=new ArrayList();
s_列表。添加(“你好”);
List i_List=new ArrayList();
i_列表。添加(10);
foo(“hello”,新整数(10));//将编译-为什么?
bar(s_list,i_list);//无法编译-可以理解
}
公共静态无效foo(T obj1,V obj2){
//做点什么
}
公共静态无效栏(列表1、列表2){
//做点什么
}
}
foo
将始终能够接受任何引用类型的两个参数,因为可以选择T
和V
作为对象
,并且任何引用类型都是对象
的子类型。所以foo
可以声明为publicstaticvoidfoo(objectobj1,objectobj2)
;这没什么区别。按照它的声明方式,foo
除了可以使用Object
执行的操作外,它的任何一个参数都不能执行任何操作,因为类型变量没有边界,因此没有理由进行任何限制,因为它们都是Object
bar
不同,因为类型变量位于类型参数中。泛型是不变的--列表
不是列表
的子类型(反之亦然),即使字符串
是对象
的子类型。因此,通过让第一个参数为typeList
,它强制T
与传递的参数的type参数精确匹配;i、 e.通过传递列表作为第一个参数,它强制T
成为String
;它不能是对象
或其他任何东西--它将不兼容。由于第二个参数的类型是List
和V
扩展T
,这意味着第二个参数的类型参数必须是String
或String
的子类型。(p.s.bar
也可以声明为稍微简单一点的public static void bar(列表列表1,foo
isObject
,等效代码-调用s_列表
时,将s_列表
更改为List s_List=new ArrayList();
;
,您的方法是已知的foo(对象t,对象e);
,您可以在调用foo(字符串t,整数e);
时看到限制。当然,您现在有了条的答案。
@TrầnAnhNam,我想我明白了。因此,当我调用泛型方法时,我需要指定类型,就像我正在创建泛型类的实例一样。因此,例如,如果我使用以下方法调用调用foo,我会得到一个编译错误,因为参数约束不成立:GenMeth.foo(“hello”,new Integer(10))对于泛型方法,只需要像我在前面的注释中所写的那样指定before-call方法。