当我使用 String 类型参数枚举向量时出现 ClassCast 异常,但使用 Integer 作为类型参数也不例外

I get ClassCast exception when I enumerate vector with String type parameter, but no exception is there with Integer as type parameter

我正在尝试使用向量并编写了一个简单的代码来通过枚举访问它的元素。

Vector v = new Vector();
    v.add("Some String");
    v.add(10);

    Enumeration e = v.elements();
    while(e.hasMoreElements()) System.out.println(e.nextElement());

使用原始类型产生预期的结果(打印元素)。但是,当我使用通用类型的枚举器时,它变得很棘手。

以字符串作为类型参数:

Vector v = new Vector();
    v.add("Some String");
    v.add(10);

    Enumeration<String> e = v.elements();
    while(e.hasMoreElements()) System.out.println(e.nextElement());

输出:

Some String

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

以整数作为类型参数:

Vector v = new Vector();
    v.add("Some String");
    v.add(10);

    Enumeration<Integer> e = v.elements();
    while(e.hasMoreElements()) System.out.println(e.nextElement());

输出:

Some String

10

这里发生了什么? 这两种情况都不应该产生 ClassCast 异常吗?

请注意,所有泛型在编译时都会被清除,这只是为了帮助编译器确认您没有犯错。此时你可能会收到几个警告,说你不应该使用原始类型(原始意味着 Vector 而不是 Vector<String> 等)。原始类型的泛型等价物是 <?> 表示您将允许任何类型(请注意,这将导致您的代码不再编译)。

您看到的行为是因为有两个(实际上还有几个,但在您的情况下使用了两个)名称为 System.out.println() 且参数类型不同的函数,这称为(方法重载):

  1. System.out.println(字符串)
  2. System.out.println(对象)

在编译时决定为您的代码调用哪个。

在 String 示例中,枚举具有通用类型 String 并将调用第一个。但是,当它从您的 Vector 传递一个 Integer 对象时,这会导致在将其转换为 String 时失败。 所以在这种情况下,编译器将您的代码转换为以下内容(大致):

Enumeration e = v.elements();
while(e.hasMoreElements()) System.out.println((String)e.nextElement());

在整数示例中,枚举具有通用类型 Integer,它将映射到 System.out.println(Object),它接受 StringInteger,所以一切顺利。

旁注:默认情况下,您应该使用 ArrayList 而不是 Vector,由于 Vector 中的遗留方法,它具有更简洁的界面。此外 Vector 它是同步的,导致不必要的开销。