0

I am creating a game in java, during the process, i implemented a generic class called ScrollingObjectHandler that takes a game object as a type parameter and handles it's movement, this game object must extends an abstract class called ScrollingObject, this is the handler's decleration:

public abstract class ScrollingObjectHandler<T extends ScrollingObject> {
    private T objects[];
    // other fields....

    @SuppressWarnings("unchecked")
    protected ScrollingObjectHandler(int size) {
        //initialization of other fields....

        objects = (T[]) new ScrollingObject[size];

        for(int i = 0;i < size;i++) {
            objects[i] = create();
        }
    }

    // init each ScrollingObject 
    protected abstract T create(); 

    // the getter for the contained array
    public T[] getAll() {
        return objects;
    }

    // rest of the code....

}

I use this class for handling 2 types of game objects; a Ground:

public class Ground extends ScrollingObject {
    // code....
}

and a TubePair:

public class TubePair extends ScrollingObject {
    // code....
}

, and this is the initialization code of the 2 handlers in my main GameWorld class:

// initialization and decleration are separated in the class
ScrollingObjectHandler<TubePair> tubePairHandler = new ScrollingObjectHandler<TubePair>() {
    @Override
    public TubePair create() {
        // returns a new TubePair
    }
};
ScrollingObjectHandler<Ground> groundHandler = new ScrollingObjectHandler<Ground>() {
    @Override
    public Ground create() {
        // returns a new Ground
    }
};

When i call getAll() to check the collision of another game object with each TubePair object using this loop :

for(TubePair tubePair : tubePairHandler.getAll()) {
    // checking collision code....
}

, i get a ClassCastException like this:

Exception in thread "LWJGL Application" java.lang.ClassCastException: [Lcom.maiconelements.flappybird.gameobjects.ScrollingObject; cannot be cast to     [Lcom.maiconelements.flappybird.gameobjects.TubePair;
    at  com.maiconelements.flappybird.world.GameWorld.update(GameWorld.java:142) (this line -> for(TubePair tubePair : tubePairHandler.getAll()))
    ....

The same problem also arises in a similar enhanced for loop that draws the Ground objects in another class, this is the getter for the Ground array from the GameWorld class :

Ground[] getGrounds() {
    return groundHandler.getAll();
}

, this is where the grounds are drawn:

for(Ground ground : world.getGrounds()) {
    // drawing code....
}

, i also get the same ClassCastException:

Exception in thread "LWJGL Application" java.lang.ClassCastException: [Lcom.maiconelements.flappybird.gameobjects.ScrollingObject; cannot be cast to     [Lcom.maiconelements.flappybird.gameobjects.Ground;
   at  com.maiconelements.flappybird.world.GameWorld.getGrounds(GameWorld.java:87)  (this line -> return groundHandler.getAll();)
    ....

What am i doing wrong here ? I am not actually trying to cast anything but the array in the ScrollingObjectHandler class, so why is this happening ?

Thanks in advance.

  • 1
    It has nothing to do with the generics, `Parent[]` is not castable to `Child[]` in Java (because you could have put other kind of children in that `Parent[]` that are not castable to `Child`). – Daniel Jan 28 '18 at 01:00
  • Thanks, i had to know that `T objects[] = (T[]) new ScrollingObject[size]` is really converted to `ScrollingObject objects[] = new ScrollingObject[size]` at runtime to understand why the exception is thrown, and it looks like when i use the array getter (whose return type is converted to `ScrollingObject[]`), the compiler tries to insert cast statements before it so the exception is thrown from there, am i right ? – Moataz Abdelnasser Jan 28 '18 at 01:40

0 Answers0