【问题标题】:In Java, why can I only restrict collection parameters using generics?在 Java 中,为什么我只能使用泛型来限制集合参数?
【发布时间】: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&lt;Object&gt; s_list = new ArrayList&lt;&gt;();
  • 当你调用foo("hello", new Integer(10));时,你的方法是已知的&lt;Object, Object&gt;foo(Object t, Object e);,你可以在调用&lt;String, Integer&gt;foo(String t, Integer e);时看到限制。当然,您现在有了bar 的答案。
  • @TrầnAnhNam,我想我明白了。因此,当我调用泛型方法时,我需要指定类型,就好像我正在创建泛型类的实例一样。例如,如果我使用以下方法调用 foo,我会收到编译错误,因为参数约束不成立: GenMeth.foo("hello", new Integer(10))
  • 对于泛型方法,只需要在调用方法之前指定,就像我在之前的评论中写的那样。

标签: java generics methods


【解决方案1】:

foo 总是能够接受任何引用类型的两个参数,因为TV 可以选择为Object,并且任何引用类型都是Object 的子类型。所以foo 还不如声明为public static void foo(Object obj1, Object obj2);没什么区别。它的声明方式,除了Object 可以做的事情之外,foo 不能用它的任何一个参数做任何事情,因为类型变量是没有界限的,所以没有理由在此之外进行任何限制他们都是Object

bar 不同,因为类型变量在类型参数中。泛型是不变的——List&lt;String&gt; 不是List&lt;Object&gt; 的子类型(反之亦然),即使StringObject 的子类型。因此,通过将第一个参数设为List&lt;T&gt; 类型,它会强制T 匹配传递参数的类型参数完全正确;即通过将List&lt;String&gt; 作为第一个参数传递,它强制TString;它不能是Object 或其他任何东西——它不兼容。并且由于第二个参数的类型是List&lt;V&gt;,并且V扩展了T,这意味着第二个参数的类型参数必须是String或者String的子类型。 (p.s. bar 也可以简单一点地声明为 public static &lt;T&gt; void bar(List&lt;T&gt; list1, List&lt;? extends T&gt; list2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 2020-07-01
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多