1

这是我的代码:

public class Sequence<T> {

    protected List<T> sequence = new ArrayList<T>();

    public Matrix<OrderedPair<T, ?>> createCartesianProduct(Sequence<?> secondSequence) {
        Matrix<OrderedPair<T, ?>> result = new Matrix<OrderedPair<T, ?>>();
        for (int rowIndex = 0; rowIndex < sequence.size(); rowIndex++) {
            Sequence<OrderedPair<T, ?>> row = new Sequence<OrderedPair<T, ?>>();
            for (int columnIndex = 0; columnIndex < secondSequence.length(); columnIndex++) {
                row.add(new OrderedPair(sequence.get(rowIndex), secondSequence.sequence.get(columnIndex)));
            }
        }
        return result;
    }
}

这在 Eclipse 中编译,但在内部 for 循环( row.add(...) )内的行上,我收到以下三个警告:

  • OrderedPair是原始类型。对泛型类型的引用OrderedPair()<T1, T2>应该被参数化。
  • 类型安全:OrderedPair 类型的表达式需要未经检查的转换才能符合OrderedPair<T, ?>
  • 类型安全:构造函数 OrderedPair(Object, Object) 属于原始类型 OrderedPair。对泛型 OrderedPair 的引用<T1, T2>应该被参数化

我想在这里使用泛型来强制执行强类型检查,但我想我对泛型的理解不足以让我看到如何。有人可以教育我吗?

谢谢,

——肯

4

5 回答 5

9

内部 for 循环中的构造函数应该具有泛型:

row.add(new OrderedPair <T, ?> (sequence.get(rowIndex), secondSequence.sequence.get(columnIndex)));

但是你不能这样使用?;所以你需要?用一个字母替换所有的 s,比如说E。然后<E>在签名中添加一个,如下所示:

public <E> Matrix<OrderedPair<T, E>> createCartesianProduct(Sequence<E> secondSequence) {

否则,编译器将不知道E来自哪里。

于 2008-12-22T19:44:02.333 回答
1

我认为你在这里有点困惑。在类型Sequence<T>中会是T什么?

如果你定义 aSequence<OrderedPair<T, ?>>那么你最终会在 T 上递归。

请看看你真正需要的是这样的东西:

public class Sequence<T> {

    protected List<T> sequence = new ArrayList<T>();

    public <T2> Matrix<OrderedPair<T, T2>> createCartesianProduct(Sequence<T2> secondSequence) {
        Matrix<OrderedPair<T, T2>> result = new Matrix<OrderedPair<T, T2>>();
        for (int rowIndex = 0; rowIndex < sequence.size(); rowIndex++) {
                Sequence<T> row = new Sequence<T>();
                for (int columnIndex = 0; columnIndex < secondSequence.length(); columnIndex++) {
                        row.add(new OrderedPair<T, T2>(sequence.get(rowIndex), secondSequence.sequence.get(columnIndex)));
                }
        }
        return result;
    }
}
于 2008-12-22T20:28:48.670 回答
1

OrderedPair 没有被泛化,但它被添加到一个被泛化的列表(序列)中。您必须使用泛型构造 OrderedPair,例如执行“new OrderedPair<...>(...)”,以消除此警告。

这里我为整个方法添加了泛型,因此返回类型与 secondSequence 的类型相匹配:

public <Z> Matrix<OrderedPair<T, Z>> createCartesianProduct(Sequence<Z> secondSequence) {
    Matrix<OrderedPair<T, Z>> result = new Matrix<OrderedPair<T, Z>>();
    for (int rowIndex = 0; rowIndex < sequence.size(); rowIndex++) {
        Sequence<OrderedPair<T, Z>> row = new Sequence<OrderedPair<T, Z>>();
        for (int columnIndex = 0; columnIndex < secondSequence.length(); columnIndex++) {
            addToRow(row, sequence.get(rowIndex), secondSequence.sequence.get(columnIndex));
        }
    }
    return result;
}

static <T, Z> void addToRow(Sequence<OrderedPair<T, Z>> seq, T t, Z z) {
    seq.add(new OrderedPair<T, Z>(t, z));
}
于 2008-12-22T20:04:13.960 回答
0

信任编译器并在调用 OrderedPair 时始终尝试使用泛型参数 :) 这不是必需的,但我认为这是一个好习惯。

由于这个原因,在 Java 中严格的泛型应用是不可能的:

类型擦除

于 2008-12-22T19:29:53.920 回答
0

您需要做的就是向构造函数添加一个泛型类型,如下所示:

row.add(new OrderedPair<T, ?>(sequence.get(rowIndex), secondSequence.sequence.get(columnIndex)));

编译器抛出错误,因为在您传递它们时OrderedPair期望接收类型而没有任何显式类型。编译器正在谈论的是,因为基本上你是在它想要的时候给构造函数<T, ?>,因此正在进行未经检查的转换,如果错误的类型意外传递,它可能会引发异常。unchecked conversion<?, ?><T, ?>

于 2008-12-22T19:43:26.483 回答