泛型类型和通配符类型之间的区别 [英] Difference between generic type and wildcard type

查看:524
本文介绍了泛型类型和通配符类型之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Generic的新手,我的问题是:两个函数有什么不同:

函数1:

  public static< E> void funct1(List< E> list1){

}

函数2 :

  public static void funct2(List<?> list){

}

谢谢。

解决方案

第一个签名表示:list1是一个Es的列表。



第二个签名表示:list是某种类型的实例列表,但我们不知道类型。

当我们尝试更改方法时,差异就变得很明显,因此需要第二个参数,它应该添加到方法内的列表中:

p>

  import java.util.List; 

公开课实验{
public static< E> void funct1(final List< E> list1,final E something){
list1.add(something);


public static void funct2(final List<?> list,final Object something){
list.add(something); //不会编译


$ $ $
$ b

第一个很好用。而且你不能将第二个参数改成任何实际编译的东西。



其实我只是发现了一个更好的证明:

  public class Experiment {
public static< E> void funct1(final List< E> list){
list.add(list.get(0));
}

public static void funct2(final List<?> list){
list.add(list.get(0)); // !!!!!!!!!!!!!!不会编译!!!!!!!!!


$ / code>

我们为什么需要<?> 时,它只会限制我们可以用它做什么(就像@Babu_Reddy_H在评论中所做的那样)。我看到了通配符版本的以下好处:




  • 调用者不必了解他传入的对象。例如如果我有一个Map列表: Map< String,List<>>< / code>我可以将它的值传递给你的函数,而不需要指定列表元素的类型。所以如果我把这样的对象分发出去,我主动限制了人们对这些对象的了解以及他们可以用它做些什么(只要它们远离它们不安全的转换)。


  • $ b

    扩展T> 。例如,考虑一个方法 List< T>合并(List <?extends T>,List<?extends T>),它将两个输入列表合并到一个新的结果列表中。当然你可以引入两个更多的类型参数,但你为什么想要?这将是过分指定的东西。


    • 最后通配符可以有下限,所以使用列表可以使 add 方法工作,而 get 不会给你任何有用的东西。当然,这触发了下一个问题:为什么泛型没有下界?


    有关更深入的答案,请参阅:何时使用通用方法以及何时使用通配符? http://www.angelikalanger.com/GenericsFAQ/FAQSections /TypeArguments.html#FAQ203


    I'm a newbie in Generic and my question is: what difference between two functions:

    function 1:

    public static <E> void funct1  (List<E> list1) {
    
    }
    

    function 2:

    public static void funct2(List<?> list) {
    
    }
    

    Thanks.

    解决方案

    The first signature says: list1 is a List of Es.

    The second signature says: list is a List of instances of some type, but we don't know the type.

    The difference becomes obvious when we try to change the method so it takes a second argument, which should be added to the list inside the method:

    import java.util.List;
    
    public class Experiment {
        public static <E> void funct1(final List<E> list1, final E something) {
            list1.add(something);
        }
    
        public static void funct2(final List<?> list, final Object something) {
            list.add(something); // does not compile
        }
    }
    

    The first one works nicely. And you can't change the second argument into anything that will actually compile.

    Actually I just found an even nicer demonstration of the difference:

    public class Experiment {
        public static <E> void funct1(final List<E> list) {
            list.add(list.get(0));
        }
    
        public static void funct2(final List<?> list) {
            list.add(list.get(0)); // !!!!!!!!!!!!!! won't compile !!!!!!!!!
        }
    }
    

    One might as why do we need <?> when it only restricts what we can do with it (as @Babu_Reddy_H did in the comments). I see the following benefits of the wildcard version:

    • The caller has to know less about the object he passes in. For example if I have a Map of Lists: Map<String, List<?>> I can pass its values to your function without specifying the type of the list elements. So

    • If I hand out objects parameterized like this I actively limit what people know about these objects and what they can do with it (as long as they stay away from unsafe casting).

    These two make sense when I combine them: List<? extends T>. For example consider a method List<T> merge(List<? extends T>, List<? extends T>), which merges the two input lists to a new result list. Sure you could introduce two more type parameters, but why would you want to? It would be over specifying things.

    • finally wildcards can have lower bounds, so with lists you can make the add method work, while get doesn't give you anything useful. Of course that triggers the next question: why don't generics have lower bounds?

    For a more in depth answer see: When to use generic methods and when to use wild-card? and http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeArguments.html#FAQ203

    这篇关于泛型类型和通配符类型之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆