Java 泛型和模板

标签 java templates generics types wildcard

我有以下 Java类定义:

import java.util.*;

public class Test {

static public void copyTo(Iterator<? extends Number> it, List<? extends Number> out) {
    while(it.hasNext())
        out.add(it.next());
}
public static void main(String[] args) {
    List<Integer> in = new ArrayList<Integer>();
    for (int i = 1; i <= 3; i++) {
        in.add(i);
    }
    Iterator<Integer> it = in.iterator();
    List<Number> out = new ArrayList<Number>();
    copyTo(it, out);
    System.out.println(out.size());
}

就是这样,我定义了方法copyTo使用 wildcardsJava .我定义 List<Number> out但是Iterator<Integer> it .我的想法是我可以将迭代器定义为 Iterator<? extends Number>那将是类型匹配。然而事实并非如此:

Test.java:13: error: no suitable method found for add(Number)
            out.add(it.next());
               ^
    method List.add(int,CAP#1) is not applicable
      (actual and formal argument lists differ in length)
    method List.add(CAP#1) is not applicable
      (actual argument Number cannot be converted to CAP#1 by method invocation conversion)
    method Collection.add(CAP#1) is not applicable
      (actual argument Number cannot be converted to CAP#1 by method invocation conversion)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Number from capture of ? extends Number
1 error

所以我继续为 copyTo 定义了另一个定义方法:

static public void copyTo(Iterator<? super Integer> it, List<? super Integer> out) {
        while(it.hasNext())
            out.add(it.next());
    }

也不行。使用 wildcards 的正确说法是什么?在这种情况下?

最佳答案

首先,你想通过向方法本身添加一个类型变量来施加约束,因为通过使用通配符你不能在两个参数之间施加约束,然后你必须考虑方法中涉及的类型的变化:

  • 你想要一个Iterator<X>作为输入其中 X至少是您要复制的数字类型的类型(或子类型)
  • 你想输出一个列表,其中 Y至多是数字类型(或父类(super class)型)的类型

这些约束是不同的,必须以不同的方式表达:

static public <T> void copyTo(Iterator<? extends T> it, List<? super T> out) {
while(it.hasNext())
    out.add(it.next());
}

这基本上是“我接受 IteratorTT 的子类型,我输出到 T 的列表或 T 的父类(super class)型”

关于Java 泛型和模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33586166/

相关文章:

java - 遍历正则表达式查找

c++ - 为什么通用模板方法定义与模板类特化不匹配?

c++ - 有条件的 constexpr 成员函数

java - 如何使用 Java 泛型来避免覆盖继承的方法(类似模板的行为)?

java - 通过转换将 List<String> 转换为 List<Object> 甚至 List<Integer>

c# - ClassName<T =""> 的含义和使用方法

java - 如何用JAVA将网页放入GUI窗口

java - 调用我创建的方法来减少变量的值不会对该值产生影响。我该如何解决这个问题?

java - 如何将图像添加到 JFrame 作为背景并仍然向其中添加其他组件?

javascript - 正则表达式匹配用大括号包裹的单词