Java 泛型 - 难以执行强类型检查

发布于 2024-07-10 21:09:41 字数 1270 浏览 5 评论 0 原文

这是我的代码:

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() 的引用应该参数化。
  • 类型安全:OrderedPair 类型的表达式需要未经检查的转换以符合 OrderedPair
  • 类型安全:构造函数 OrderedPair(Object, Object) 属于原始类型 OrderedPair。 对泛型类型 OrderedPair 的引用应该参数化

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

谢谢,

--肯

Here's my code:

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;
    }
}

This compiles in Eclipse, but on the line within the inner for loop ( row.add(...) ) I get the following three warnings:

  • OrderedPair is a raw type. References to generic type OrderedPair()<T1, T2> should be parameterized.
  • Type Safety: The expression of type OrderedPair needs unchecked conversion to conform to OrderedPair<T, ?>
  • Type safety: The Constructor OrderedPair(Object, Object) belongs to the raw type OrderedPair. References to generic type OrderedPair<T1, T2> should be parameterized

I would like to use generics to enforce strong type-checking here, but I guess my understanding of generics is not sufficient to allow me to see how. Could someone educate me?

Thanks,

-- Ken

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

是伱的 2024-07-17 21:09:41

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

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

但你不能像这样使用 ? ; 因此您需要将所有 ? 替换为字母,例如 E。 然后将 添加到签名中,如下所示:

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

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

The constructor in the inner for loop should have generics:

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

But you can't use ? like this; so you'll need to replace all the ?s with a letter, say E. Then add an <E> into the signature, like this:

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

Otherwise, the compiler won't know where the E came from.

静谧 2024-07-17 21:09:41

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

在这里,我向整个方法添加了泛型,因此返回类型与 secondarySequence 的类型匹配:

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));
}

The OrderedPair is not generified but it's added to a list (Sequence) which is generified. You have to construct the OrderedPair with generics, e.g. do "new OrderedPair<...>(...)", to get rid of this warning.

Here I have added generics to the whole method, so the return type matches the secondSequence's type:

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));
}
清秋悲枫 2024-07-17 21:09:41

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

如果您定义一个 Sequence> 那么您最终会在 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;
    }
}

I think that you are a bit confused here. In the type Sequence<T> what will be the T?

If you define a Sequence<OrderedPair<T, ?>> then you end up with recursion on T.

Please see if what you really need is something like this:

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;
    }
}
尴尬癌患者 2024-07-17 21:09:41

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

在 Java 中严格泛型应用是不可能的,因为:

类型擦除

Trust compiler and try to use generic parameters always when calling for OrderedPair :)
It's not required but I think it's a good practice.

Strict generic applying in Java is not possible because of this:

Type erasure

猫腻 2024-07-17 21:09:41

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

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

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

All you need to do is add a generic type to your constructor, like so:

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

The compiler is throwing errors since OrderedPair expects to receive types <T, ?> while you are passing them without any explicit type. The unchecked conversion the compiler is talking about is since basically you are giving the constructor <?, ?> while it wants <T, ?> hence the unchecked conversion that is going on, and which might throw an exception if the wrong type accidentally gets passed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文