所以,我正在使用2D数组作为我正在研究的平台物理系统。不幸的是,由于各种原因,2D阵列需要通用类型。
我正在用一些java Collections(精确的链表)动态构建表面,然后用一些hacky trickery将它们转换为2D数组。这当前有效,给我适当的2D通用数组:*
LinkedList<PhysSurface<P>> leftSurfaces = new LinkedList<PhysSurface<P>>();
LinkedList<PhysSurface<P>> rightSurfaces = new LinkedList<PhysSurface<P>>();
LinkedList<PhysSurface<P>> topSurfaces = new LinkedList<PhysSurface<P>>();
LinkedList<PhysSurface<P>> bottomSurfaces = new LinkedList<PhysSurface<P>>();
// Add surfaces to the lists
GenericArray<PhysSurface<P>[]> base = new GenericArray<PhysSurface<P>[]>(4);
PhysSurface<P>[][] surfaces = base.elements();
surfaces[0] = leftSurfaces.toArray(new GenericArray<PhysSurface<P>>().elements());
surfaces[1] = rightSurfaces.toArray(new GenericArray<PhysSurface<P>>().elements());
surfaces[2] = topSurfaces.toArray(new GenericArray<PhysSurface<P>>().elements());
surfaces[3] = bottomSurfaces.toArray(new GenericArray<PhysSurface<P>>().elements());
但是,当我尝试将这一切都放入这样的通用静态方法时:
@SuppressWarnings("unchecked")
public static <T> T[][] to2DArray(Collection<T>... collections)
{
GenericArray<T[]> base = new GenericArray<T[]>(collections.length);
T[][] array = base.elements();
for(int i = 0; i < collections.length; i++)
array[i] = collections[i].toArray(new GenericArray<T>().elements());
return array;
}
然后我调用这样的方法:
PhysSurface<P>[][] surfaces = GenericsUtils.to2DArray(leftSurfaces, rightSurfaces, topSurfaces, bottomSurfaces);
然后一切崩溃,给我一个ClassCastException,说它不能将类型Object转换为类型PhysSurface。堆栈跟踪在这里:
Exception in thread "main" java.lang.ClassCastException: [[Ljava.lang.Object; cannot be cast to [[Lcom.meg.utils._2D.platformer.phys.environment.surface.PhysSurface;
at com.meg.chaos_temple.test.world.PhysTestWorld$TestMap.<init>(PhysTestWorld.java:487)
at com.meg.chaos_temple.test.world.PhysTestWorld$TestPlayer.<init>(PhysTestWorld.java:245)
at com.meg.chaos_temple.test.world.PhysTestWorld.<init>(PhysTestWorld.java:95)
at com.meg.chaos_temple.main.ChaosDebug.createWorld(ChaosDebug.java:72)
at com.meg.jrabbit.engine.main.BaseGame.start(BaseGame.java:56)
at com.meg.jrabbit.engine.loop.Loop.run(Loop.java:44)
at com.meg.jrabbit.engine.main.BaseGame.run(BaseGame.java:40)
at com.meg.jrabbit.engine.main.StandardGame.run(StandardGame.java:85)
at com.meg.chaos_temple.main.ChaosDebug.main(ChaosDebug.java:19)
据我所知,泛型方法不是使用泛型类型T,而是默认创建一个Object [] []并在返回时尝试强制转换。如果这是正在发生的事情,为什么这在放入静态方法时不起作用?如果没有,那到底是怎么回事?
答案 0 :(得分:3)
不幸的是,T[][] array
在运行时与Object[][] array
相同。通用类型参数将在运行时删除;只有编译器知道它。
解决方案是传递对象的类:Class<T>
。
import java.reflect.Array;
...
public static <T> T[][] to2DArray(Class<T> klazz, Collection<T>... collections)
{
T[][] array = (T[][]) Array.newInstance(klazz, collections.length,
collections[0].size());
//...
array[i] = (T[]) Array.newInstance(klazz, collections[i].size());
return array;
}
对于多维结果,Array.newInstance的强制转换是必需的。
不再@SuppressWarnings("unchecked")
!
而不是传递collections[0].size()
,它可能足以通过0
。