Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,为什么只能使用泛型限制集合参数?_Java_Generics_Methods - Fatal编程技术网

在Java中,为什么只能使用泛型限制集合参数?

在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)

下面我有两个通用方法。两者都有两个参数化类型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) {

        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
不同,因为类型变量位于类型参数中。泛型是不变的--
列表
不是
列表
的子类型(反之亦然),即使
字符串
对象
的子类型。因此,通过让第一个参数为type
List
,它强制
T
与传递的参数的type参数精确匹配;i、 e.通过传递
列表作为第一个参数,它强制
T
成为
String
;它不能是
对象
或其他任何东西--它将不兼容。由于第二个参数的类型是
List
V
扩展
T
,这意味着第二个参数的类型参数必须是
String
String
的子类型。(p.s.
bar
也可以声明为稍微简单一点的
public static void bar(列表列表1,
foo
is
Object
,等效代码-调用
s_列表
时,将
s_列表
更改为
List s_List=new ArrayList();
,您的方法是已知的
foo(对象t,对象e);
,您可以在调用
foo(字符串t,整数e);
时看到限制。当然,您现在有了
条的答案。
@TrầnAnhNam,我想我明白了。因此,当我调用泛型方法时,我需要指定类型,就像我正在创建泛型类的实例一样。因此,例如,如果我使用以下方法调用调用foo,我会得到一个编译错误,因为参数约束不成立:GenMeth.foo(“hello”,new Integer(10))对于泛型方法,只需要像我在前面的注释中所写的那样指定before-call方法。