了解上限和下限?在Java泛型中 [英] Understanding upper and lower bounds on ? in Java Generics

查看:239
本文介绍了了解上限和下限?在Java泛型中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很难理解这个通配符参数。我有几个关于这方面的问题。


  1. 作为类型参数只能在方法中使用。例如: printAll(MyList< ;? extends Serializable>)我不能使用定义类作为类型参数。


  2. 我了解的上限。 printAll(MyList< ;? extends Serializable>)表示: printAll 会打印 MyList 如果它具有实现 Serialzable 接口的对象。

    我有点问题与 super printAll(MyList< ;? super MyClass>)表示: printAll 将打印 MyList 如果它的对象是 MyClass 或任何延伸 MyClass 的类 MyClass )。



  3. 改正我我错了。简单来说,只有 T E

    >或 K V N 可用作用于定义泛型类的类型参数。 只能用于方法



    更新1:

      public void printAll(MyList< ;? super MyClass>){
    // code code code
    }

    Accordint to Ivor Horton's book, MyList <?超级MyClass> 表示我可以打印 MyList ,如果它具有 MyClass 或任何对象它实现的接口或类。也就是说, MyClass 下限。它是继承层次结构中的最后一个类。这意味着我最初的假设是错误的。



    因此,如果 MyClass 看起来像:

      public class MyClass extends Thread implements ActionListener {
    // whatever
    }

    然后,如果

    将打印 printAll() MyClass 列表中的
    2.有 Thread的对象或<$ c $ 列表



    更新2:中的c> ActionListener



    因此,在阅读了许多问题的答案后,我的理解是:
    $ b $ ol

  4. ?扩展T 意味着任何延伸 T 的类。因此,我们指的是 T 子元素。因此, T 是上限。继承层次结构中最上面的类


  5. ?超级T 意味着任何 超级 STRONG>。因此,我们指的是 T 的所有父母。因此, T 是下限。继承层次结构中最低级的类



  6. 解决方案


    作为类型参数只能在方法中使用。例如: printAll(MyList< ;? extends Serializable>)我无法用类型参数定义<?类。


    通配符()不是一个正式的类型参数,而是可以是用作类型参数。在你给的例子中,?扩展Serializable 作为类型参数给定为 printAll 的泛型类型 MyList 方法的参数。



    方法也可以声明类型参数类,例如:

      static< T extends Serializable> void printAll(MyList< T> myList)




    上。 printAll(MyList< ;? extends Serializable>)表示 printAll将打印MyList,如果它具有实现Serialzable接口的对象


    更准确地说,它意味着对 printAll 的调用只有在传递给 MyList 与一些泛型类型是或实现 Serializable 。在这种情况下,它会接受 MyList< Serializable> MyList< Integer> 等。


    我对 super 有点问题。 printAll(MyList<?super myClass>)表示 printAll将打印MyList,如果它包含MyClass的对象或任何扩展MyClass的类 MyClass)

    super 为界的通配符是 lower 绑定。所以我们可以说,调用 printAll 时,只有在它传递了一个 MyList 以及一些泛型类型时才会进行编译即 MyClass 或某些超类型的 MyClass 。因此,在这种情况下,它会接受 MyList< MyClass> MyList< MyParentClass> MyList< Object>


    因此,如果MyClass看起来像这样:

      public class MyClass extends Thread然后,printAll()将实现ActionListener {
    //任意
    }

    打印如果


    1. 列表中有MyClass的对象

    2. 有Thread或ActionListener的对象在列表中


    您现在处于正确的轨道上。但我想说,例如如果在列表中存在 MyClass 的对象有问题,它将会打印。这听起来像是你定义运行时行为 - 泛型都是关于编译时检查。例如,将无法传递 MyList< MySubclass> 作为 MyList的参数。超级MyClass> ,尽管它可能包含 MyClass 的实例。我会将它改写为:

    调用 printAll(MyList<?super MyClass>)它被传递给a:


    1. MyList< MyClass>

    2. MyList< Thread>

    3. MyList< Runnable>

    4. MyList< ActionListener>

    5. MyList< EventListener>

    6. MyList< Object>

    7. MYLIST< ;?其中 X MyClass Thread code>, Runnable ActionListener EventListener ,或 Object




    阅读了许多问题的答案,这里是我对
    的理解:


    ?扩展T 意味着任何扩展T 的类。因此,我们指的是T的子女
    。因此,T是上限。继承层次结构中最高级的



    ? super T 表示T的 super 的任何类/接口。因此,我们是
    ,指的是T的所有父项。 T因此是下限。继承层次结构中
    最低级的类


    关闭,但我不会说 T T 的父母,因为这些界限都是包含 - 它比 T 或其子类型和 T 或其超类型更准确。


    I am really having a tough time understanding the wild card parameter. I have a few questions regarding that.

    1. ? as a type parameter can only be used in methods. eg: printAll(MyList<? extends Serializable>) I cannot define classes with ? as type parameter.

    2. I understand the upper bound on ?. printAll(MyList<? extends Serializable>) means: "printAll will print MyList if it has objects that implement the Serialzable interface."
      I have a bit of an issue with the super. printAll(MyList<? super MyClass>) means: "printAll will print MyList if it has objects of MyClass or any class which extends MyClass (the descendants of MyClass)."

    Correct me where I went wrong.

    In short, only T or E or K or V or N can be used as type parameters for defining generic classes. ? can only be used in methods


    Update 1:

    public void printAll(MyList<? super MyClass>){
        // code code code
    }
    

    Accordint to Ivor Horton's book, MyList<? super MyClass> means that I can print MyList if it has objects of MyClass or any of the interfaces or classes it implements. That is, MyClass is a lower bound. It is the last class in the inheritance hierarchy. This means my initial assumption was wrong.

    So, say if MyClass looks like:

    public class MyClass extends Thread implements ActionListener{
        // whatever
    }
    

    then, printAll() will print if
    1. There are objects of MyClass in the list
    2. There are objects of Thread or ActionListener in the List


    Update 2:

    So, after having read the many answers to the question, here is my understanding:

    1. ? extends T means any class which extends T. Thus, we are referring to the children of T. Hence, T is the upper bound. The upper-most class in the inheritance hierarchy

    2. ? super T means any class / interface which is super of T. Thus we are referring to all the parents of T. T is thus the lower bound. The lower-most class in the inheritance hierarchy

    解决方案

    ? as a type parameter can only be used in methods. eg: printAll(MyList<? extends Serializable>) I cannot define classes with ? as type parameter.

    A wildcard (?) isn't a formal type parameter, but rather can be used as a type argument. In the example you give, ? extends Serializable is given as a type argument to the generic type MyList, of the printAll method's parameter.

    Methods can also declare type parameters like classes, for example:

    static <T extends Serializable> void printAll(MyList<T> myList)
    

    I understand the upper bound on ?. printAll(MyList<? extends Serializable>) means printAll will print MyList if it has objects that implement the Serialzable interface

    More accurately, it means a call to printAll will compile only if it is passed a MyList with some generic type that is or implements Serializable. In this case it would accept a MyList<Serializable>, MyList<Integer>, etc.

    I have a bit of an issue with the super. printAll(MyList<? super MyClass>) means printAll will print MyList if it has objects of MyClass or any class which extends MyClass (the descendants of MyClass)

    A wildcard bounded with super is a lower bound. So we could say a call to printAll will compile only if it is passed a MyList with some generic type that is MyClass or some super-type of MyClass. So in this case it would accept MyList<MyClass>, e.g. MyList<MyParentClass>, or MyList<Object>.

    So, say if MyClass looks like:

    public class MyClass extends Thread implements ActionListener{
        // whatever
    }
    

    then, printAll() will print if

    1. There are objects of MyClass in the list
    2. There are objects of Thread or ActionListener in the list

    You're on the right track. But I think saying e.g. "it will print if there are objects of MyClass in the list" is problematic. That makes it sound like you're defining runtime behavior - generics are all about compile time checks. For example wouldn't be able to pass a MyList<MySubclass> as an argument for MyList<? super MyClass>, even though it might contain instances of MyClass, by inheritance. I would reword it to:

    A call to printAll(MyList<? super MyClass>) will compile only if it is passed a:

    1. MyList<MyClass>
    2. MyList<Thread>
    3. MyList<Runnable>
    4. MyList<ActionListener>
    5. MyList<EventListener>
    6. MyList<Object>
    7. MyList<? super X> where X is MyClass, Thread, Runnable, ActionListener, EventListener, or Object.

    So, after having read the many answers to the question, here is my understanding:

    ? extends T means any class which extends T. Thus, we are referring to the children of T. Hence, T is the upper bound. The upper-most class in the inheritance hierarchy

    ? super T means any class / interface which is super of T. Thus we are referring to all the parents of T. T is thus the lower bound. The lower-most class in the inheritance hierarchy

    Close, but I wouldn't say "children of T" or "parents of T", since these bounds are inclusive - it would be more accurate to say "T or its subtypes", and "T or its supertypes".

    这篇关于了解上限和下限?在Java泛型中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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