上回说到,如果传入cast()的目标数组长度小于源数组,怎么办呢?
怎么办?怎么办?凉拌当然不行了。
由于Generic Erasure的存在,让我们没有可能采用类似 new T[X] 这样的简单快捷的实现,
可以做的只能是采用
obj.getClass().newInstance()
这样的方法了。然而,obj.getClass().newInstance()只能产生一个元素,怎样生成一串呢?
各位观众,现在,我们隆重介绍:java.lang.reflect.Array 同学,请大家鼓掌!
java.lang.reflect.Array.newInstance(Class<?> componentType, int length);
还有一个需要注意的是,如果我们对于cast(Object[] oa, T[] ta)中的ta采用
Class c = ta[0].getClass();
来获得类,那是很不专业的,因为ta[0]通常是null值,我们不能用它来处理一个non-static method?
于是我们用Class c = ta.getClass().getComponentType();
下面是参考代码,我留了一个有bug的版本做参考。cast2()是可用的- 1 public class ObjectArrayClassCastTest {
- 2 public static void main(String args []){
- 3 Object[] oa = new Object[3];
- 4 oa[0] = "Hello";
- 5 oa[1] = "world";
- 6 oa[2] = "!";
- 7
- 8 String[] sa = new String[oa.length];
- 9 String[] sa1 = new String[0];
- 10 //System.arraycopy(oa, 0, sa, 0, oa.length);
- 11 sa = cast2(oa, sa);
- 12 sa1 = cast2(oa, sa1);
- 13 for(String s : sa) {
- 14 System.out.println(s);
- 15 }
- 16 for(String s : sa1) {
- 17 System.out.println(s);
- 18 }
- 19 }
- 20
- 21 //with bug
- 22 public static <T> T[] cast(Object[] oa, T[] ta){
- 23 if(ta.length >= oa.length)
- 24 System.arraycopy(oa, 0, ta, 0, oa.length);
- 25 else
- 26 ta = cast(oa, ta[0]);
- 27 return ta;
- 28 }
- 29
- 30 public static <T> T[] cast(Object[] oa, T obj){
- 31 Class c = obj.getClass();
- 32 Object o = java.lang.reflect.Array.newInstance(c, oa.length);
- 33 T[] to = (T[])o;
- 34 System.arraycopy(oa, 0, to, 0, oa.length);
- 35 return to;
- 36 }
- 37
- 38 public static <T> T[] cast2(Object[] oa, T[] ta){
- 39 if(ta.length < oa.length)
- 40 ta = (T[])java.lang.reflect.Array.newInstance(
- 41 ta.getClass().getComponentType(), oa.length);
- 42 System.arraycopy(oa, 0, ta, 0, oa.length);
- 43 return ta;
- 44 }
- 45 }
复制代码 对于Collection.toArray(T[])的实现,请参考java SDK的源代码。
事实上在java SDK src中采用的是Arrays.copyOf()方法来简化实现,而copyOf()的实质就是我上面说
的这一堆东西。所以说,原版本大致上就是和我这个差不多了。
关于这个话题说得有点远,不好意思。
[ 本帖最后由 key 于 30-6-2009 10:42 编辑 ] |