猿问

何时使用 java 通用通配符?

评论中指出,问题正在制造混乱。所以,我已经编辑了这个问题,如果它仍然造成混乱,请告诉我。


考虑下面的代码:


类员工{}


类 ContractEmployee 扩展 Employee{ }


类 PermanentEmployee 扩展 Employee{ } ...


任何人都可以提供以下两种情况之间的基本区别以及何时使用哪一种


情况1


public <T extends Employee> void empTest(ArrayList<T> list)


public <? extends Employee> void empTest(ArrayList<?> list)

案例:2


public void empTest(ArrayList<? extends Employee> list)


public void empTest(ArrayList<T extends Employee> list)


米脂
浏览 140回答 2
2回答

www说

首先,您的问题非常合理,尽管通过您的示例,很难解释/理解这些差异。在所有变体中,您都希望定义一个方法empTest()来接受雇员的 ArrayList 或雇员的子类。你这样做public&nbsp;void&nbsp;empTest(ArrayList<?&nbsp;extends&nbsp;Employee>&nbsp;list)&nbsp;{&nbsp;...&nbsp;}那么,其他语法变体的用途是什么?让我们使用不同的示例,因为您的empTest()方法不需要任何其他内容。比如说,我们想使用类似addEmp(list, emp);.&nbsp;第一个想法可能是:public&nbsp;void&nbsp;addEmp(ArrayList<Employee>&nbsp;list,&nbsp;Employee&nbsp;emp)&nbsp;{&nbsp;...&nbsp;}但这不会完成这项工作,因为您将无法将 an 传递ArrayList<ContractEmployee>到方法中。下一次尝试:public&nbsp;void&nbsp;addEmp(ArrayList<?&nbsp;extends&nbsp;Employee>&nbsp;list,&nbsp;Employee&nbsp;emp)&nbsp;{&nbsp;...&nbsp;}现在它接受列表,但它也允许您将 aArrayList<ContractEmployee>与 a 组合传递PermanentEmployee,并且不允许将 a 添加PermanentEmployee到 an&nbsp;ArrayList<ContractEmployee>。编译器会将方法主体中添加员工的行标记为非法。所以,我们在这里需要的是检查在两个地方使用相同类型的员工,这就是命名类型参数可以用来做什么。public&nbsp;<T&nbsp;extends&nbsp;Employee>&nbsp;void&nbsp;addEmp(ArrayList<T>&nbsp;list,&nbsp;T&nbsp;emp)&nbsp;{&nbsp;...&nbsp;}这表示:可以传入ArrayList的任何子类型中的Employee,我们称之为子类型T。然后emp参数也必须来自相同的子类型T(或由于正常的类继承而来自子子类型)。如果是Employee与否对方法没有影响,你甚至可以写public&nbsp;<T>&nbsp;void&nbsp;addEmp(ArrayList<T>&nbsp;list,&nbsp;T&nbsp;emp)&nbsp;{&nbsp;...&nbsp;}总结一下:<... extends SomeClass>如果需要比普通<SomeClass>构造更多的可变性,请使用构造。如果它只是您需要可变性的一个地方,通常不需要为子类引入名称,因此<? extends SomeClass>在方法的参数列表中即可完成这项工作。如果你需要在多个地方使用相同的子类,你需要给它一个名字,所以<T extends SomeClass>在返回类型声明前面使用类似的东西,并且T在参数列表中使用不带尖括号的东西。关于语法: - 如果您需要为类型参数引入名称,则在返回类型之前完成。- 在方法返回类型或方法参数列表中,您只能使用已存在的名称,或使用未命名的通配符构造。

三国纷争

不完整的解释,但你会从这里开始。我们需要在泛型中遵循PECS模式。佩奇表示P roducer Ë xtends和ç onsumer小号UPER。在您下面的行中,public void empTest(ArrayList list)您基本上是在提供列表,该列表将作为生产者在该方法中进一步使用。现在您可能知道,泛型只是编译时的错觉,会在运行时被删除,您在 mrthod empTest 中的代码期待特定员工的列表。例如,如果您将 Fruit 作为 Orange 和 Apple 的超类,则不应将 Orange 和 Apple 的列表同时提供给消费者并将其限制为 Apple 或 Orange。是否有意义?我猜是。
随时随地看视频慕课网APP

相关分类

Java
我要回答