当我使用String类型参数枚举vector时,我得到了ClassCast异常,但没有异常,其中Integer作为类型参数

Har*_*ngh 12 java generics enumeration vector

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

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

    Enumeration e = v.elements();
    while(e.hasMoreElements()) System.out.println(e.nextElement());
Run Code Online (Sandbox Code Playgroud)

使用原始类型会按预期生成结果(打印元素).但是,当我使用泛型类型的枚举器时,它会变得棘手.

使用String作为类型参数:

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

    Enumeration<String> e = v.elements();
    while(e.hasMoreElements()) System.out.println(e.nextElement());
Run Code Online (Sandbox Code Playgroud)

输出:

一些字符串

线程"main"java.lang.ClassCastException中的异常:java.lang.Integer无法强制转换为java.lang.String

使用Integer作为类型参数:

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

    Enumeration<Integer> e = v.elements();
    while(e.hasMoreElements()) System.out.println(e.nextElement());
Run Code Online (Sandbox Code Playgroud)

输出:

一些字符串

10

这里发生了什么?两个案例都不应该产生ClassCast异常吗?

Thi*_*ler 5

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

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

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

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

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

Enumeration e = v.elements();
while(e.hasMoreElements()) System.out.println((String)e.nextElement());
Run Code Online (Sandbox Code Playgroud)

在整数示例枚举具有泛型类型Integer,将映射到System.out.println(Object),这同时接受StringInteger,所以一切顺利.

在旁注中:默认情况下,您应该使用ArrayList而不是Vector,由于传统方法,它具有更清晰的界面Vector.同时Vector它是同步造成不必要的开销.