【发布时间】:2017-11-03 02:58:59
【问题描述】:
下面我有两个通用方法。两者都有两个参数化类型 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
}
}
【问题讨论】:
-
foo中最不具体的类型是Object,等效代码 - 将s_list更改为List<Object> s_list = new ArrayList<>(); -
当你调用
foo("hello", new Integer(10));时,你的方法是已知的<Object, Object>foo(Object t, Object e);,你可以在调用<String, Integer>foo(String t, Integer e);时看到限制。当然,您现在有了bar的答案。 -
@TrầnAnhNam,我想我明白了。因此,当我调用泛型方法时,我需要指定类型,就好像我正在创建泛型类的实例一样。例如,如果我使用以下方法调用 foo,我会收到编译错误,因为参数约束不成立: GenMeth.
foo("hello", new Integer(10)) -
对于泛型方法,只需要在调用方法之前指定,就像我在之前的评论中写的那样。