在Java中是否存在通配符(?)的实际用例



当通配符?extendssuper一起使用时,我没有得到它在Java中的实际使用情况。

Oracle Java官方文档展示了一个将数字添加到列表中并对其进行汇总的示例:

private static double sumOfList(List<? extends Number> list) {
double sum = 0.0;
for (Number number : list) {
sum += number.doubleValue();
}
return sum;
}

根据我的理解,List<? extends Number> list并不意味着";Number对象的实例和Number"的可能子类的对象的列表;而是";单个类型的对象的列表,其必须是或扩展类型"数字";。没关系。

直到我尝试了这个代码:

List<Number> numberList = new ArrayList<Number>();
numberList.add(Integer.valueOf(123));
numberList.add(Double.valueOf(2.34));
numberList.add(Float.valueOf(3.45f));

实例可以通过隐式向上转换到数字引用添加到"数字"列表中。然后,这个数字列表可以与sumOfList方法一起使用,如上所示。但这些元素不会是单一类型的。那么,为什么有人会把extends?一起使用呢?

我没有得到的另一件事是将通配符与super一起使用。可以定义一个类型的下界。Oracle的官方文档显示了这个例子:

public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 10; i++) {
list.add(i);
}
}

问题是,这对于像向列表中添加数字这样的简单事情来说非常有效。但是显示的代码也适用于这样的列表:

List<Object> list = new ArrayList<Object>();
list.add(Integer.valueOf(123));
list.add(Double.valueOf(2.34));
list.add(new Person("John", "Doe"));

因此,只要调用方法,就可以对实际数字做任何有用的事情,比如——我不知道——算术运算——代码可能会很好地工作。但当涉及到John Doe条目时,用于数字的代码会失败。

那么,有人能澄清extendssuper关键字与?运算符结合的实际应用吗?

那么,为什么有人会将extends?一起使用呢?

因为您可能没有要传递给它的List<Number>。例如,您可以将List<Integer>List<BigInteger>等传递给sumOfList

如果您没有声明它接受List<? extends Number>,而是声明它接受了List<Number>,那么您只能将List<Number>传递给它——List<Integer>不是List<Number>的子类型。


addNumbers方法而言:您只需要某种List,可以安全地向其添加Integer的实例(或子类型[因为它是最终的,所以没有子类型]或null(。

这就是List<? super Integer>的全部含义:向其中添加Integer的实例是安全的。

List<Object>传递给该方法是安全的,因为所有Integer都是Object,所以将Integer添加到该列表是安全的。

同样,如果您已将该方法声明为接受List<Object>(或List<Integer>(,那么您可以传递给它的就只有这些:List<Object>(或分别为List<Integer>(。比如说,你不能通过List<Number>


那么,有人能澄清extendssuper关键字与?运算符结合使用的实际用途吗?

通配符的实际使用是以增加API方法的灵活性,如上所示:它允许您声明一个将一系列相关类型作为输入的方法。

您也可以在输出中使用通配符,但应该避免这样做,因为通配符最终出现在调用站点的值类型中,并且通常看起来很混乱。

1。那么,为什么有人会使用extends with呢?不管怎样

当通配符被用作"Unbounded like"时,我们不能执行写入或删除操作;列出<gt&";,因为编译器不知道它是什么类型,比如:

// not allowed
public static void displayList(List<?> list) {
list.add(1);
}
// allowed
public static void displayList(List<? super Integer> list) {
list.add(1);
}

2.那么,有人能澄清extends和super关键字与的实际实际应用吗?操作员

它是使用一些设计模式和原则的一个很好的组合,我想到的最简单的一个是将它与接口分离原则一起使用。

interface Worker {
void work();
}
interface Sleeping {
void sleep();
}
class Human implements Worker, Sleeping {
@Override
public void work() {}
@Override
public void sleep() {}
}
class Robot implements Worker {
@Override
public void work() {}
}
public static void main(String[] args) {
Human human1 = new Human();
Human human2 = new Human();
List<Human> humans = List.of(human1, human2);
displayIfSleeping(humans);
Robot robot1 = new Robot();
Robot robot2 = new Robot();
List<Robot> robots = List.of(robot1, robot2);
displayIfSleeping(robots); // error
}
public static void displayIfSleeping(List<? extends Sleeping> workers) {
// display only workers who are sleeping
}

这是一个很好的方式,可以明确地表明,如果你必须迭代员工,你只希望他们是可以睡觉的人。

相关内容

  • 没有找到相关文章

最新更新