使用[]调用时出现奇怪的java.lang.ClassCastException

使用[]调用时出现奇怪的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

我正在使用LibDGX库进行游戏。我遇到了常见的异常
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]
}