我正在尝试向量并编写一个简单的代码来通过枚举来访问它的元素。
Vector v = new Vector();
v.add("Some String");
v.add(10);
Enumeration e = v.elements();
while(e.hasMoreElements()) System.out.println(e.nextElement());
使用原始类型会按预期生成结果(打印元素)。但是,当我使用泛型类型的枚举器时,它会变得棘手。
使用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());
输出:
一些字符串
线程中的异常&#34; main&#34; 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());
输出:
一些字符串
10
这里发生了什么? 两个案例都不应该产生ClassCast异常吗?
答案 0 :(得分:5)
请注意,所有泛型都在编译时被删除,这只是为了帮助编译器确认您没有犯错。可能你会在这一点上得到几个警告,说你不应该使用原始类型(原始意味着Vector
而不是Vector<String>
等)。原始类型的泛型等价物是<?>
,表示您将允许任何类型(请注意,这将导致您不再编译代码)。
您看到的行为是因为有两个(实际上是几个,但在您的情况下使用了两个)具有名称System.out.println()
和不同参数类型的函数,这称为(方法重载):
在编译时,决定为您的代码调用哪个。
在String示例中,枚举具有泛型类型String
,并将调用第一个类型。但是当它从Integer
传递Vector
对象时,这会导致将其转换为String时失败。
所以在这种情况下,编译器会将您的代码转换为以下(粗略地):
Enumeration e = v.elements();
while(e.hasMoreElements()) System.out.println((String)e.nextElement());
在整数示例中,枚举具有泛型类型Integer
,它将映射到System.out.println(Object)
,它同时接受String
和Integer
,因此一切顺利。
在旁注中:默认情况下,您应该使用ArrayList
而不是Vector
,由于Vector
中的遗留方法,它具有更清晰的界面。同样Vector
它被同步导致不必要的开销。