当前位置: 首页 > 面试题库 >

了解上限和下限?在Java泛型中

燕富
2023-03-14
问题内容

我真的很难理解通配符参数。我对此有一些疑问。

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

  2. 我了解上限?printAll(MyList<? extends Serializable>)表示:“ 如果有实现该 接口的 对象, printAll 则将打印。MyList``Serialzable
    我对有点问题superprintAll(MyList<? super MyClass>)表示:“ 如果具有 或扩展的任何类 (的后代
    ), printAll 则将打印。MyList``MyClass``MyClass``MyClass

纠正我哪里出错了。

简而言之,只有TEKVN可用作定义泛型类的类型参数。?只能用于方法

更新1:

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

根据Ivor Horton的书,这MyList<? super MyClass>意味着我可以打印MyList它是否具有MyClass其实现的对象或任何实现的接口或类。也就是说,MyClass是一个
下界 。它是继承层次结构中的最后一个类。这意味着我最初的假设是错误的。

因此,假设是否MyClass看起来像:

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

然后,printAll()将打印,如果
1.有对象MyClass列表
2.有对象ThreadActionListenerList

更新2:

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

  1. ? extends T表示 任何扩展的类T。因此,我们指的是的 子项T。因此, T 是上限。继承层次结构中最高级的类

  2. ? super T表示 属于super的任何类/接口T。因此,我们指的是的所有 父母TT 因此是下限。继承层次结构中最底层的类


问题答案:

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

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

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

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

我了解上限?printAll(MyList<? extends Serializable>)表示
printAll如果具有实现Serialzable接口的对象,则将打印MyList

更准确地说,这意味着 只有将传递给 具有或实现的某种通用类型的时,
对的调用printAll才会编译MyList``Serializable。在这种情况下,它会接受MyList<Serializable>MyList<Integer>等等。

我对有点问题superprintAll(MyList<? super MyClass>)表示
printAll如果具有MyClass对象或任何扩展MyClass的类MyClass 的后代), 则将打印MyList。

以限制的通配符super是一个 下限 。因此,我们可以说
printAll仅当通过传递MyList具有MyClass或的某种超类型的时,才会编译的调用MyClass。因此,在这种情况下,它将接受MyList<MyClass>,例如MyList<MyParentClass>MyList<Object>

因此,假设MyClass看起来像:

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

然后,printAll()将在以下情况下打印

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

您走在正确的轨道上。但是我认为说“例如,如果MyClass列表中有对象,它将打印”是有问题的。这听起来像是您在定义运行时行为-
泛型都是关于编译时检查的。例如,即使它可能通过继承包含的实例,也无法将a
MyList<MySubclass>作为参数传递给。我将其改写为:MyList<? super MyClass>``MyClass

printAll(MyList<? super MyClass>)只有在以下情况下,对的调用才会编译:

  1. MyList<MyClass>
  2. MyList<Thread>
  3. MyList<Runnable>
  4. MyList<ActionListener>
  5. MyList<EventListener>
  6. MyList<Object>
  7. MyList<? super X>其中XMyClassThreadRunnableActionListenerEventListener,或Object

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

? extends T表示 任何扩展T的类 。因此,我们指的是T的子代。因此, T是上限。 继承层次结构中最高级的类

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

T亲,但我不会说“的孩子”或“其父母T”,因为这些范围是 包含在内的 -说“ T或其子类型”和“ T或其超类型” 会更准确。



 类似资料:
  • 在这个例子中:假设我需要一个selectionSort的版本,它可以使用调用方提供的外部可比性来处理任何类型T。 第一次尝试: 假设我有: 定义的车辆类别 创建VehicleComparator实现比较器,同时根据车辆的价格比较车辆。 创建的卡车扩展车辆 实例化卡车[]arr;VehicleComparator MyComparator 现在,我有: 这个宣言会起作用,但我不完全确定我一直在做什么

  • 问题内容: 我试图了解下限和上限通配符的行为。 尝试编译以下代码时遇到问题。 为了弄清楚问题,我还尝试了下限通配符。幸运的是或不幸的是,代码可以很好地编译,但是却造成了很多混乱。 有人可以解释一下这两个代码段如何工作。如果有人可以提供其他示例/链接,那就太好了。 如果我在上面做错了什么,请纠正我。 提前致谢。 问题答案: 表示“未知类型”。 表示某种对象的集合。此“某种类型”可以是作为其子类或自身

  • 问题内容: 我试图理解有界类型,而不是完全掌握它们的要点。 有一个提供此用例的有限泛型示例: 如果要限制可以作为参数化类型的类,为什么不将所有参数化全部忘掉而拥有: 然后,任何扩展/实现的类都可以与此类一起使用。 还有一个附带的问题:当Java 类是final 时,如何扩展第一个示例? 问题答案: 当Java Integer类为final时,T在第一个示例中如何扩展Integer? 只能是,因此这

  • 本文向大家介绍请解释一下extends 和super 泛型限定符相关面试题,主要包含被问及请解释一下extends 和super 泛型限定符时的应答技巧和注意事项,需要的朋友参考一下 考察点:JAVA泛型 (1)泛型中上界和下界的定义 上界<? extend Fruit> 下界<? super Apple> (2)上界和下界的特点 上界的list只能get,不能add(确切地说不能add出除nul

  • 在运用泛型时,类型参量常常必须使用 trait 作为限定(bound)来明确规定一个类型实现了哪些功能。例如下面的例子用到了 Display trait 来打印,所以它要求 T 由 Display 限定,也就是说 T 必须实现 Display。 // 定义一个函数 `printer`,接受一个泛型类型 `T`,其中 `T` 必须 // 实现 `Display` trait。 fn printer<

  • 问题内容: 我有一个具有通用类型的Interface Foo- 有另一个实现该接口的Bar类,但我想要的是Bar的通用Type应该是Interface A和B类型的集合,使用以下定义,它给出了编译器错误- 您能提出实现此目标的正确方法吗? 我只能在方法级别使用多个范围吗? 问题答案: 这行不行吗?