【问题标题】:java.util.ArrayList cannot be cast to java.util.Vectorjava.util.ArrayList 不能转换为 java.util.Vector
【发布时间】:2014-06-03 19:28:40
【问题描述】:

我正在尝试用来自对象列表readExcel.readSheet(0) 的数据填充 tableModel,使用以下代码:

 TableModel tableModel = new DefaultTableModel(
    new Vector<List<Object>>(readExcel.readSheet(0)
       .subList(1, readExcel.readSheet(0).size())), 
    new Vector<Object>(readExcel.readSheet(0).get(0)));  

但我遇到了这个异常

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Vector  

我认为这是关于通过列表实例化 Vector,但是通过 Vector 的 javadoc,我们可以看到使用集合实例化 Vector 是可能的。

我的代码 sn-p 有什么问题?

【问题讨论】:

  • 我认为您需要阅读更多有关铸造及其工作原理的信息。对于您的解决方案,您可以使用向量中的 addAll 方法在数组列表中添加元素
  • 是的,你不懂“演员表”。这一点也不稀奇,因为这是一个难以掌握的概念,而且可能比理解它更容易被误解。
  • @Vinay 你能推荐一个我可以阅读它的好地方吗?感谢您的 addAll 方法技巧
  • 使用泛型进行铸造是很棘手的。意识到您不能从 List[A extends B] 转换为 List[B] 似乎并不明显。
  • 使用泛型进行强制转换非常棘手,因为它不是真正的操作,而只是您用来欺骗编译器的操作。运行时不知道对象是 Vector&lt;Object&gt; 还是 Vector&lt;String&gt;

标签: java casting jtable tablemodel


【解决方案1】:

“cast”是程序员发给编译器的指令;它说“理论上我在这里传递的类型可能不是所需类型的子类型,但我知道它会在运行时出现,所以不要给出错误说这是错误的类型。”

编译器只能将一种类型转换为另一种类型,如果这两种类型一起在一个继承行中,即如果它们直接或间接地从另一个继承。

所以我猜你有些复杂的构造函数和/或方法调用中的一个参数需要一个 ArrayList,而你正在传递一个 Vector。如果构造函数或方法需要 ArrayList,则不能将 Vector 传递给它。

【讨论】:

  • 我会说“编译器只允许将一种类型转换为另一种类型,前提是这两种类型在一个继承行中”。
【解决方案2】:

我不完全确定,但我认为答案是泛型不尊重子类型。 E>g。如果 B 扩展了 A,那么您可能认为可以将 List[B] 转换为 List[A],但我认为您实际上不能。虽然您可以 addAll 将列表中的所有项目放入列表中。

因此

List<ArrayList<Object>> 

不是一种

List<List<Object>>

并且转换失败,因为 readExel 的返回类型是前者而不是后者。

造成这种情况的原因主要与模糊的边缘情况有关。在 Effective Java 中有一个关于它的项目

public class test {

static class Foo {

}

static class Moo extends Foo {

}

/**
 * @param args
 */
public static void main(String[] args) {

    List<Moo> list = new ArrayList<Moo>();
    for(int i=0; i<10; i++){
        list.add(new Moo());
    }

    List<Foo> listFoo = (List<Foo>) list;

}

}

生成编译器错误,因为

List<Moo> 

不是

的子类型
List<Foo>

所以如果你替换你的代码应该可以工作

Vector<List<Object>> 

Vector<ArrayList<Object>>

【讨论】:

  • 感谢@phil 的解释,但 readExcel.readSheet(sheetNumber) 返回 List>,用 Vector> 更改 Vector> 不起作用要么:)
  • 在这种情况下,您可以拆分行并使用堆栈跟踪,以便我们可以查看问题是创建向量,还是尝试转换的表?
  • Vector 和 ArrayList 这两种类型共享 AbstractList 作为共同的祖先,因此可以设计一个接口来接受其中任何一种。但是,这种共同的祖先并不意味着您可以在预期的地方替换一个。与泛型无关。
  • Vector 实现 List Hot Licks
【解决方案3】:

您可以将超类转换为子类,反之亦然。

但是 Vector 和 ArrayList 不共享任何父子关系。

尽管两者都有共同的祖先 (List &gt; Collection &gt;iterable)。

因此,您可以将向量转换为列表。但不能直接转换为 arrayList。例如

public class test {

static class Foo {

}

static class Moo extends Foo {

}

/**
 * @param args
 */
public static void main(String[] args) {

    List<Moo> list = new ArrayList<Moo>();
    for(int i=0; i<10; i++){
        list.add(new Moo());
    }

    List<Foo> listFoo = (List<Foo>) list;

}

}

生成编译器错误,因为 List 不是 List 的子类型

因此,如果将 Vector> 替换为 >

,您的代码应该可以工作

【讨论】:

  • 因此,如果将 Vector> 替换为 > ,您的代码应该可以工作?我想你在这里错过了一些东西
  • 你只能将一个对象转换成它本来的样子。例如,您不能强制转换对 HashMap 的引用以使其成为 LinkedHashMap 引用,但您可以将对 LinkedHashMap 的引用强制转换为 HashMap,并且您可以将存储在 HashMap 引用变量中的 LinkedHashMap 引用强制转换为存储在一个 LinkedHashMap。
猜你喜欢
  • 1970-01-01
  • 2017-10-29
  • 2020-12-20
  • 2023-03-29
  • 2013-07-11
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多