2016-06-14 13 views
0

Hier ist mein Code:Java Generika - ein generisches zum anderen Casting

public class AnimationManager<STATE> { 


private Map<STATE, Animation> animationMap = new HashMap<STATE, Animation>(); 


public void addAnimation(STATE state, BufferedImage[] frames, int frameDuration){ 
     animationMap.put(state, new Animation(frames, frameDuration)); 
} 

public <E extends Enum<E>> void initAnimations(Player player, Constants.Heros chosen_hero, Class<E> heroStates){ 
     LinkedList<BufferedImage[]> frames = AssetsManager.getHeroGraphics(chosen_hero); 

     assert frames != null; 

     player.width = frames.get(0)[0].getWidth(); 
     player.height = frames.get(0)[0].getHeight(); 

     for(int i=0;i<frames.size();i++) 
      addAnimation(heroStates.getEnumConstants()[i],frames.get(0),15); 

} 

} 

An dieser Linie:

addAnimation(heroStates.getEnumConstants()[i],frames.get(0),15); 

Compiler ruft: Wrong 1. Argument Typ, gefunden 'E', erforderlich ‚STATE ".

Wenn initAnimations() Methode ist in einer anderen Klasse (ohne STATE) kompiliert und funktioniert wie ein Charme. Wie ist das möglich, dass er den ersten Parameter nicht erhalten und in einen STATE-Typ umwandeln will?

Antwort

0

Der Typparameter STATE ist unbeschränkt und kann mit jeder Klasse aufgerufen werden. Der Typparameter E ist auf eine Unterklasse von Enum beschränkt. Die Variablen heldStates sind eine Klasse, was bedeutet, dass die Methode getEnumConstants() ein Array von E zurückgibt (was ein Array einer Unterklasse von Enum bedeutet). Das kann nicht sicher in den Typ von STATE umgewandelt werden.

Je nach Ihren spezifischen Anforderungen können Sie von hier aus auf verschiedene Arten vorgehen. Wenn Gießen vermieden werden kann, wäre das vorzuziehen.

Wenn Sie wissen, dass STATE Typ-Parameter immer eine ENUM sein werden, könnten Sie eine Schranke für STATE setzen und den Parameter Typen E überspringen insgesamt:

class AnimationManager<STATE extends Enum<STATE>> 
... 
void initAnimations(Player player, Heros chosen_hero, Class<STATE> heroStates) 

Andernfalls, wenn Sie diesen Staat nicht kennen eine Enumeration ist, dann können Sie die Klasse Reflexion Ausübung des Erhaltens der Aufzählungstypen zu vermeiden, indem Sie den Anrufer Ihrer initAnimations lassen() -Methode, um sie:

void initAnimations(Player player, Heros chosen_hero, List<STATE> heroStates) 
... 
addAnimation(heroStates.get(i), frames.get(0), 15); 

und der Aufruf wäre so etwas wie

AnimationManager<Foo> animationManager = ...; 
animationManager.initAnimations(null, null, Arrays.asList(Foo.values())); 

Die dritte Option, die ich wirklich nicht mag, wäre zu werfen. In diesem Fall müssen Sie nur die problematische Linie ändern

addAnimation((STATE)heroStates.getEnumConstants()[i], frames.get(0), 15); 

, dass eine Warnung für einen ungeprüften Guss erzeugen, die das Generika-Typ-System bedeutet, kann nicht garantieren, dass Sie nicht mit ClassCastException s enden, wenn Sie laufen dein Code.

Viel Glück mit Ihrem Spiel!

+0

Aw, das ist jetzt klar. Vielen Dank! –