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

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

问题描述

我真的很难理解通配符参数.我有几个问题.

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

  2. 我了解 的上限?.printAll(MyList<? extends Serializable>) 意思是:printAll 将打印 MyList 如果它有实现 的对象Serialzable 接口."
    我对 super 有点问题.printAll(MyList) 意思是:printAll 将打印 MyList 如果它有 MyClass<的对象/code> 或任何扩展 MyClass 的类(MyClass 的后代)."

纠正我哪里出错了.

简而言之,只有T or E or K or V or N 可以用作定义泛型类的类型参数.? 只能在方法中使用
<小时>更新 1:

public void printAll(MyList){//代码代码代码}

根据 Ivor Horton 的书,MyList 意味着我可以打印 MyList 如果它有 MyClass 的对象或者它实现的任何接口或类.也就是说,MyClass 是一个下限.它是继承层次结构中的最后一个类.这意味着我最初的假设是错误的.

所以,假设 MyClass 看起来像:

public class MyClass extends Thread 实现 ActionListener{//任何}

那么,printAll() 将打印 if
1.列表中有MyClass的对象
2、List
中有ThreadActionListener的对象<小时>更新 2:

所以,在阅读了问题的许多答案后,这是我的理解:

  1. <代码>?extends T 表示任何扩展 T 的类.因此,我们指的是 T孩子.因此,T 是上限.继承层次结构中最上层的类

  2. <代码>?super T 意味着任何类/接口,它是Tsuper.因此,我们指的是 T 的所有 父项.T 因此是下限.继承层次结构中最底层的类

解决方案

? 作为类型参数只能在方法中使用.例如:printAll(MyList) 我不能用 ? 作为类型参数定义类.

通配符 (?) 不是正式的类型参数,而是可以用作类型参数.在你给出的例子中,?extends Serializable 作为类型参数提供给 printAll 方法的参数的泛型类型 MyList.

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

static void printAll(MyList myList)

<块引用>

我了解 的上限?.printAll(MyList 表示 printAll 将打印 MyList,如果它有实现 Serialzable 接口的对象

更准确地说,这意味着printAll的调用只有在传递一个MyList时才会编译,该MyList具有某种是或实现Serializable的泛型类型.在这种情况下,它将接受 MyListMyList 等.

<块引用>

我对 super 有点问题.printAll(MyList) 表示 printAll 将打印 MyList 如果它有 MyClass 的对象或任何扩展 MyClass 的类(MyClass 的后代)

super 为界的通配符是一个下界.所以我们可以说printAll的调用只有在传递一个MyListMyClass或一些泛型类型时才会编译MyClass 的超类型.所以在这种情况下,它会接受 MyList,例如MyList,或 MyList.

<块引用>

所以,假设 MyClass 看起来像:

public class MyClass extends Thread 实现 ActionListener{//任何}

那么,printAll() 将打印如果

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

你走在正确的轨道上.但我想说例如如果列表中有 MyClass 的对象,它将打印"是有问题的.这听起来像是在定义运行时行为 - 泛型都是关于编译时检查的.例如,不能将 MyList 作为 MyList,即使它可能通过继承包含 MyClass 的实例.我会改写为:

printAll(MyList) 的调用只有在传递 a 时才会编译:

  1. MyList
  2. MyList
  3. MyList
  4. MyList
  5. MyList
  6. MyList
  7. MyList 其中 XMyClassThreadRunnableActionListenerEventListenerObject.
  8. <块引用>

    所以,在阅读了问题的许多答案之后,这是我的理解:

    <代码>?extends 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天全站免登陆