是否可以在Java 1.4中的列表中使用泛型?

时间:2011-06-12 05:24:47

标签: generics java jdk1.4

我必须使用Java 1.4并使用arraylist结构。现在我需要做一些重新分解,如果我可以使用泛型,它会有所帮助。目前我有这样的代码

ArrayList rows = new ArrayList();

这是一个简单的ArrayList。但现在“行”变量变得越来越复杂,需要定义一个“行”类。我现在想要做的事情就像你在J2SE 1.5中看到的那样

ArrayList<Row> rows = new ArrayList();

如果没有使用第三方解决方案,谷歌的拖网不会暴露任何答案。如果不使用第三方解决方案/开源项目(如果可能),我的代码如何在1.4中进行更改以适应这种情况?

5 个答案:

答案 0 :(得分:9)

在JDK 1.5中引入了泛型。所以你不能在1.4中使用它们。但是,您可以使用JDK 1.5编译器,但使用带有-target 1.4 javac选项的类来定位1.4,同时保留-source 1.5选项以指示您的源是1.5兼容的。在这种情况下,您可以使用泛型,因为它们不应影响结果类。​​

See the section on Cross-Compilation Options

答案 1 :(得分:4)

泛型倾向于在处理集合时解决Java 1.4或更早版本中我认为“天真的演员”的问题。在Java 1.5+中,您放置的行:

ArrayList<Row> rows = new ArrayList();

会发出警告,正确的通用代码是

ArrayList<Row> rows = new ArrayList<Row>();

这告诉编译器您的ArrayList对象应该只包含Row类型。

但是,由于Java 1.5向后兼容不包含该语法的大量库,而是之前的代码:

ArrayList rows = new ArrayList();

泛型显然无法使用这些较旧的库 - 因此泛型只是编译时选项 - 1.5和1.4类实际上是等效的(减去后面添加的任何内部重构/新方法),因为它们实际上是处理任何Object类型的ArrayList实现。

1.5代码只是为您添加直接演员。

在1.4代码中,假设您想迭代ArrayList。这种天真的方式如下:

for(Iterator rowIterator = rows.iterator(); rowIterator.hasNext(); ) {
    Row row = (Row) rowIterator.next();
    // Do something with the row.
}

Java 1.5的代码完全等同于朴素的演员版本。它需要你告诉编译器它一行并为你做代码。因此,语法糖的好处更好(这对每个循环语法使用较新的,但它生成与上述循环相同的代码):

for(Row row : rows) {
   // Do something with the row
}

因此,如果您想使用仅包含行的ArrayList,您仍然可以。但是没有办法让编译器检查 ArrayList只包含所有行(尽管编译器提供了这个检查,但仍然可以发送一个ArrayList包含其他类型的对象,因为ArrayList仍然只是真正处理Object类型,并且泛型在运行时被擦除 - 剩下的就是你不再看到的天真的强制转换代码了。

非天真的变体是检查每个实例并自己抛出一个带有信息性消息的ClassCastException(而不是让程序抛出一个带有默认消息):

for(Iterator rowIterator = rows.iterator(); rowIterator.hasNext(); ) {
    Object shouldBeRow = rowIterator.next();
    if(!(shouldBeRow instanceof Row)) {
        throw new ClassCastException("The object " + shouldBeRow + " is not an instance of Row - only Rows should be present in the list!");
    }
    Row row = (Row) shouldBeRow;
    // Do something with the row.
}

但是,通常没有人这样做 - 好的文档可以使这个问题没有实际意义,因为它会给调用者提供正确的集合负担,因此你可以让JVM抛出ClassCastException。

答案 2 :(得分:2)

是的,你可以。使用1.5编译器,并使用

javac -target jsr14 ............

这将生成java 1.4类,但允许泛型。

此开关只能用于非字节代码可见1.5功能。例如,您不能使用Enums或1.5中引入的新方法。但是泛型很好,因为它们并不存在于字节代码中。

答案 3 :(得分:0)

不,您不能在JDK 1.4中使用它们。它们是在JDK1.5中引入的

答案 4 :(得分:-1)

你所要做的就是施展它们。如果将“错误”类型放入列表中,这可能值得运行时异常。

Row arow = (Row) rows.get(0);

for ($i=0; i<rows.size(); $i++){
    Row element = (Row) rows.get($i);
    element.printCells();
    (...)
}