当前位置: 代码迷 >> J2SE >> 泛型数组转换的有关问题
  详细解决方案

泛型数组转换的有关问题

热度:69   发布时间:2016-04-23 20:32:57.0
泛型数组转换的问题
我有一个类里面封装了一个Map,这个类要实现一个values方法,和Map的values类似,但返回的不是Collection,而需要是一个数组(已有代码不好修改,只能接受数组),但是发现无法将Object[]转换为泛型类型的数组,看下面的代码。

以下代码可以编译通过,但是运行就会报ClassCastException
public class MapTest<K, V> {
private Map<K, V> map;

public MapTest() {
map = new HashMap<>();
}

public void add(K key, V value) {
map.put(key, value);
}

public V[] values() {
Object[] vs = map.values().toArray();

return (V[]) vs;
}

public static void main(String[] args) {
MapTest<Integer, String> map = new MapTest<>();

map.add(1, "first");
map.add(2, "second");
map.add(3, "third");

String[] values = map.values();  // 这里报错 ClassCastException
for (String value : values) {
System.out.println(value);
}
}

}

我找了一些资料,说Java运行时不存在泛型,所以将Object[]转换为V[]是没有作用的,因为运行时Java不知道V是什么,有的又说数组之间不存在继承关系的不能转换,比如String[]可以转换成Object[],但Object[]不能转换为String[]。

后来我想了一个办法,传入一个Class类,然后用反射创建一个这个类的数组。
	public V[] values(Class<? extends V> c) {
Object[] vs = (Object[]) Array.newInstance(c, map.size());
int i = 0;
for (Entry<K, V> e : map.entrySet()) {
vs[i++] = e.getValue();
}
return (V[]) vs;
}

这样虽然可以运行通过了,但是依然需要去修改已有的代码,不太方便,而且个人觉得这种方法有点投机取巧的味道,所以想问下有没有其他方法能实现我的需求的?
------解决方案--------------------
没什么好办法,传class是最直接的了。
------解决方案--------------------
public V[] values() {
V[] vs = (V[]) map.values().toArray();

return (V[]) vs;
}


map.add(1, "first");
map.add(2, "second");
map.add(3, "third");

Object[] values = map.values(); // 这里报错 ClassCastException
for (Object value : values) {
//System.out.println((String)value);
System.out.println(value);
}


------解决方案--------------------
用Class很好啊。
String[] 和 Object[] 本质上是两个不同的类,所以转换会有一点问题。
这个和List<Object>与List<String>有很大区别,后者本质上还是同一个类,运行时转换问题很小。
  相关解决方案