繁体   English   中英

我在Java中的泛型测试不起作用!

[英]My generics test in Java doesn't work!

我正在做一些Java学习,特别是在泛型领域。

我对C#中的泛型非常熟悉,但在Java中,这是一个完全不同的故事。

我使用了一些适合测试的样本,我能够用Java复制我的大部分C#代码。

但是,当我尝试以下示例时,它不起作用:

private static <T> void swapKundeData(ArrayList<T> data, int index1, int index2) {

    T temporary = (T) data.get(index1);

    data.set(index1, data.get(index2)); //Does not compile
    data.set(index2, temporary); //Does not compile

}

我收到的错误是:

在ArrayList类型中的方法set(int,capture#5-of?extends ExtendTest)不适用于参数(int,ExtendTest)

相当于这个在C#中运行得很好 - 所以发生了什么?

我已经读到Java在泛型方面受到了很多批评。 这是批评的一部分吗? 数据变量的Remove和Add方法工作得很好。

好吧,我会用

List<Kunde> 

代替

ArrayList<?>

因为你无论如何都要去昆德:)。

它不起作用的原因是您不知道传递的对象的类型。 因此,如果您设置一个可能是错误类型的Kunde(因为使用ArrayList <?>,您可以传递ArrayList <String>并在其上设置Kunde将是错误的类型)。

另一种可能性是:

private static <T> void swapData(List<T> data, int index1, int index2) {

    T temporary = data.get(index1);

    data.set(index1, data.get(index2)); //Does compile
    data.set(index2, temporary); //Does compile

}

要完成我的咆哮,只需使用Collections的swap方法。

http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#swap(java.util.List,int,int

如果你知道你的ArrayList包含Kunde对象,那么你应该声明方法参数ArrayList<Kunde> ; 没有必要使用通配符。 正如您所看到的,它会导致编译时类型错误。

有关该问题的完整说明,请参阅http://download.oracle.com/javase/tutorial/extra/generics/wildcards.html

你的问题的原因是你声明了一种ArrayList<?> ,这意味着“一个列表应该只包含某种类型,但我不知道哪一种”。 这样做的结果是,你从列表中取出的对象唯一知道的是它们是Object类型,因为一切都是(除了原语,它不能在集合中)。 但更重要的是,您不能将任何内容放入列表中,因为您不知道它受约束的类型。

这就是为什么使用? 通配符很少适合。 在几乎所有情况下,您应该使用具体类型或命名有界类型:

private static void swapKundeData(List<Kunde> data, int index1, int index2) {
    Kunde temporary = data.get(index1);
    data.set(index1, data.get(index2));
    data.set(index2, temporary);
}

请注意List接口的使用,这使得代码可以更灵活地接受它所接受的内容。

private static <T> void swap(List<T> data, int index1, int index2) {
    T temporary = data.get(index1);
    data.set(index1, data.get(index2));
    data.set(index2, temporary);
}

这是真正通用的解决方案,它是类型安全的,但不需要知道列表元素的类型。 你实际上并没有通过使用Generics获得任何类型的安全性( Object也可以这样做),但你可以返回一个交换元素,编译器会知道返回值与列表元素的类型相同。

问题是Eclipse。

我没有保存文件,所以显然没有重新编译。

哇,我对IDE的无能力和烦恼感到非常满意,比如速度。

那好吧。

我注意到这个问题已被编辑,以前的答案没有多大意义。

从查看问题编辑,值得注意的是,如果您希望客户端看到如下方法:

public static void swapKundeData(List<?> data, int index1, int index2) {

但是你想要实现:

public static <T> void swapKundeData(List<T> data, int index1, int index2) {

可以捕获通配符,并且具有客户端友好表单的方法可以转发为实现友好的形式:

public static void swapKundeData(List<?> data, int index1, int index2) {
    swapKundeDataImpl(data, index1, index2)
}

private static <T> void swapKundeDataImpl(List<T> data, int index1, int index2) {

(我在这里假设“kunde”不是一个粗鲁的词。)

总结Oli所说的内容,你不能分配给“未知类型”的集合吗? 因为java不知道应该去那里。 但是,由于每个“未知类型”仍然是一个对象,因此它们可以安全地调用“getter”方法,因为它们将始终返回Object类型的对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM