使用[]调用时出现奇怪的java.lang.ClassCastException
我正在使用LibDGX库进行游戏。我遇到了常见的异常使用[]调用时出现奇怪的java.lang.ClassCastException,java,reflection,libgdx,kotlin,Java,Reflection,Libgdx,Kotlin,我正在使用LibDGX库进行游戏。我遇到了常见的异常ClassCastException,但它发生在奇怪的情况下 我正在使用LibGDX库中的类 只有在使用[]操作时,我的这一行才会出现错误。 val tex = animation.keyFrames[0] 如果我将其更改为get(),错误将消失 tex = animation.keyFrames.get(0) 这里是完整的方法。我简化了这个例子 override fun create() { val frames = Arra
ClassCastException
,但它发生在奇怪的情况下
我正在使用LibGDX库中的类
只有在使用[]
操作时,我的这一行才会出现错误。
val tex = animation.keyFrames[0]
如果我将其更改为get()
,错误将消失
tex = animation.keyFrames.get(0)
这里是完整的方法。我简化了这个例子
override fun create() {
val frames = Array<TextureRegion>()
frames.add(TextureRegion(Texture("badlogic.jpg")))
val animation = Animation(frames)
val tex1 = animation.keyFrames.get(0) // Compiles
val tex = animation.keyFrames[0] // error - [Ljava.lang.Object; cannot be cast to [Lcom.badlogic.gdx.graphics.g2d.TextureRegion;
}
你能告诉我发生这种情况的原因吗?或者可能是一个bug 编辑:在旧版本的libGDX中,
动画
不使用数组
的反射功能。如果它有,你就不会有这个错误,因为数组的类型是正确的!它应该在1.9.7版的libGDX中。注意:创建数组时,必须指定数组的类
这是最近在中修复的。
但是,以下带有get
和[]
的“bug”导致数组的字节码不同,可能仍然值得报告/查询
这很有趣
反编译
val tex1 = animation.keyFrames.get(0)
val tex = animation.keyFrames[0]
给予
给予
作为
数组的实际类型是对象[]
!因此,对TextureRegion[]
的转换失败
对我来说,这似乎是一个libGDX错误
我能够用Java中的一个简单类很容易地重现这一点:
public class JavaObjWithArray<T> {
private T[] items;
public JavaObjWithArray(T[] items) {
this.items = (T[]) new Object[items.length];
System.arraycopy(items, 0, this.items, 0, items.length);
}
public T[] getItems() {
return items;
}
}
fun main(args: Array<String>) {
val obj = JavaObjWithArray(arrayOf("a", "b"))
val one = obj.items.get(0)
val two = obj.items[0]
}
公共类JavaObjWithArray{
私人物品;
公共JavaObjWithArray(T[]项){
this.items=(T[])新对象[items.length];
System.arraycopy(items,0,this.items,0,items.length);
}
公共T[]getItems(){
退货项目;
}
}
趣味主线(args:Array){
val obj=JavaObjWithArray(arrayOf(“a”、“b”))
val one=obj.items.get(0)
val二=对象项[0]
}
这还将在带有[]
的行上抛出ClassCastException
!此外,字节码也有相同的区别
Java(和Kotlin)中缺少泛型数组确实会产生问题。Java中有两种主要的解决方案:
public class JavaObjWithArray<T> {
private T[] items;
public JavaObjWithArray(T[] items) {
this.items = (T[]) new Object[items.length];
System.arraycopy(items, 0, this.items, 0, items.length);
}
public T[] getItems() {
return items;
}
}
fun main(args: Array<String>) {
val obj = JavaObjWithArray(arrayOf("a", "b"))
val one = obj.items.get(0)
val two = obj.items[0]
}
- 存储一个
对象[]
并在get
- 存储
对象[]
,但将其强制转换为T[]
这是一个问题-因为数组的实际类型是Object[]
。因此,这些“通用”数组不应该公开!我可以理解为什么libGDX会这样做,即提高性能并消除方法调用的小开销,但这绝对不安全
然而,get
和[]
不同的事实可能是一个bug。也许调查这一点或提交错误报告会有所帮助
这不是同一个动画类,没有这个constructor@1blustone好了,现在好多了?但这没有意义。。。我试着让它更具可读性。无论如何都会出错。啊,现在有道理了。您正在查看当前的源代码,它还没有发布。这个bug似乎已经修复,应该在下一个版本中出现,请参阅我的答案:)谢谢您的精彩解释。这真的很有帮助。这个问题困扰了我很长时间。所以现在我们终于决定这是Kotlin bug?然后我将创建一个问题。@icarumbas带有[]
和get
的零件,看起来是这样的。此外,文档中还指出,[]
和运算符get
应具有相同的效果。[]
的IntelliJ文档甚至会导致get
。
val tex = animation.keyFrames[0]
ALOAD 2
INVOKEVIRTUAL com/badlogic/gdx/graphics/g2d/Animation.getKeyFrames ()[Ljava/lang/Object;
CHECKCAST [Lcom/badlogic/gdx/graphics/g2d/TextureRegion;
ICONST_0
AALOAD
ASTORE 4
public Animation (float frameDuration, Array<? extends T> keyFrames) {
this.frameDuration = frameDuration;
T[] frames = (T[]) new Object[keyFrames.size];
for (int i = 0, n = keyFrames.size; i < n; i++) {
frames[i] = keyFrames.get(i);
}
setKeyFrames(frames);
}
T[] frames = (T[]) new Object[keyFrames.size];
public class JavaObjWithArray<T> {
private T[] items;
public JavaObjWithArray(T[] items) {
this.items = (T[]) new Object[items.length];
System.arraycopy(items, 0, this.items, 0, items.length);
}
public T[] getItems() {
return items;
}
}
fun main(args: Array<String>) {
val obj = JavaObjWithArray(arrayOf("a", "b"))
val one = obj.items.get(0)
val two = obj.items[0]
}