Java中的通配符(?)有实际的实际用例吗?
Is there an actual practical usecase of the wildcard character (?) in Java?
当与 extends
或 super
一起使用时,我没有得到 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 的可能子 类 的对象”,而是“单一类型的对象列表,必须是或扩展类型 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 条目时,用于数字的代码将失败。
那么谁能阐明extends
和super
关键字结合?
运算符的实际应用?
So why would anyone use extends
with ?
anyways?
因为您可能没有 List<Number>
可以传递给它。例如,您可以将 List<Integer>
、List<BigInteger>
等传递给 sumOfList
.
如果您没有声明它接受 List<? extends Number>
,而是接受 List<Number>
,您只能将 List<Number>
传递给它 - List<Integer>
不是 List<Number>
.
的子类型
就 addNumbers
方法而言:您只需要某种 List
即可安全地向其中添加 Integer
的实例(或子类型 [其中有 none, 因为它是最终的], 或 null
).
这就是全部 List<? super Integer>
的意思:可以安全地向其中添加 Integer
的实例。
将 List<Object>
传递给该方法是安全的,因为所有 Integer
都是 Object
,因此将 Integer
添加到该列表是安全的。
同样,如果您将方法声明为接受 List<Object>
(或 List<Integer>
),那么您只能传递给它:List<Object>
(或a List<Integer>
,分别)。你不能通过它,比如说,List<Number>
.
So can anyone clarify the actual practical use of the extends
and super
keywords in combination with the ?
operator?
通配符的实际用途是增加API方法的灵活性,如上图所示:它允许你声明一个单一的方法,它接受一个范围相关类型作为输入。
您也可以在输出中使用通配符,但应该避免这种情况,因为通配符最终会出现在调用站点的值的类型中,并且通常看起来杂乱无章。
1.那么为什么有人会使用 extends with 呢?不管怎样?
像"List>"这样的Unbounded使用通配符时,我们无法进行写入或删除操作,因为编译器无法知道它是什么类型,如:
// 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 Segregation Principle 一起使用。
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
}
这是一种很好的方式,可以明确表明如果您必须遍历工作人员,您只希望他们成为可以睡觉的人。
当与 extends
或 super
一起使用时,我没有得到 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 的可能子 类 的对象”,而是“单一类型的对象列表,必须是或扩展类型 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 条目时,用于数字的代码将失败。
那么谁能阐明extends
和super
关键字结合?
运算符的实际应用?
So why would anyone use
extends
with?
anyways?
因为您可能没有 List<Number>
可以传递给它。例如,您可以将 List<Integer>
、List<BigInteger>
等传递给 sumOfList
.
如果您没有声明它接受 List<? extends Number>
,而是接受 List<Number>
,您只能将 List<Number>
传递给它 - List<Integer>
不是 List<Number>
.
就 addNumbers
方法而言:您只需要某种 List
即可安全地向其中添加 Integer
的实例(或子类型 [其中有 none, 因为它是最终的], 或 null
).
这就是全部 List<? super Integer>
的意思:可以安全地向其中添加 Integer
的实例。
将 List<Object>
传递给该方法是安全的,因为所有 Integer
都是 Object
,因此将 Integer
添加到该列表是安全的。
同样,如果您将方法声明为接受 List<Object>
(或 List<Integer>
),那么您只能传递给它:List<Object>
(或a List<Integer>
,分别)。你不能通过它,比如说,List<Number>
.
So can anyone clarify the actual practical use of the
extends
andsuper
keywords in combination with the?
operator?
通配符的实际用途是增加API方法的灵活性,如上图所示:它允许你声明一个单一的方法,它接受一个范围相关类型作为输入。
您也可以在输出中使用通配符,但应该避免这种情况,因为通配符最终会出现在调用站点的值的类型中,并且通常看起来杂乱无章。
1.那么为什么有人会使用 extends with 呢?不管怎样?
像"List>"这样的Unbounded使用通配符时,我们无法进行写入或删除操作,因为编译器无法知道它是什么类型,如:
// 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 Segregation Principle 一起使用。
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
}
这是一种很好的方式,可以明确表明如果您必须遍历工作人员,您只希望他们成为可以睡觉的人。