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

问题描述

| 我必须使用Java 1.4,并且正在使用arraylist结构。现在,我需要进行一些重构,如果可以使用泛型,这将有所帮助。目前我有这样的代码
ArrayList rows = new ArrayList();
这是一个简单的ArrayList。但是现在\“ rows \”变量变得越来越复杂,需要定义\“ Row \”类。我现在想做一些您在J2SE 1.5中看到的事情
ArrayList<Row> rows = new ArrayList();
如果不对第三者解决方案进行一些复杂的使用,通过Google进行的搜寻就不会暴露任何答案。如果不使用第三方解决方案/开源项目,我的代码将如何更改以适应1.4中的要求(如果可能)?     

解决方法

        泛型是在JDK 1.5中引入的。因此,您不能在1.4中使用它们。但是,您可以使用JDK 1.5编译器,但使用带有
-target 1.4
javac选项的类来定位目标1.4,同时保留
-source 1.5
选项以指示源与1.5兼容。在这种情况下,可以使用泛型,因为它们不会影响结果类。 请参阅“交叉编译选项”部分     ,        泛型倾向于解决我在Java 1.4或更早版本中处理Collections时认为“天真强制转换”的问题。在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。     ,        是的你可以。使用1.5编译器,并使用
javac -target jsr14 ............
这将生成Java 1.4类,但允许泛型。 此开关只能用于非字节代码可见的1.5功能。例如,您不能使用Enums或1.5中引入的新方法。但是泛型很好,因为它们实际上没有出现在字节码中。     ,        不,您不能在JDK 1.4中使用它们。它们是在JDK1.5中引入的     ,        您所要做的就是铸造它们。如果将“错误的”类型放入列表中,则可能会导致运行时异常。
Row arow = (Row) rows.get(0);

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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...