2012-11-09 13 views
14

Sto cercando di scrivere un metodo per restituire tutti gli oggetti che corrispondono alla classe ottiene come parametro:instanceof Classe <?> parametro

public class Scenario extends View { 

    ... 

    private Actor[] actors = new Actor[1024]; 

    ... 

    public Actor[] getActors(Class<?> cls) { 
     //Count actors corresponding to class cls 
     int cnt = 0;  
     for (int i = 0; i<actorsCount; i++) 
      if (actors[i] instanceof cls) cnt++; 


     //Build a new array; 
     Actor[] clsActors = new Actor[cnt]; 

     //Fill it 
     for (int j = 0, k=0; j<cnt; k++) 
      if (actors[k] instanceof cls) 
       clsActors[j++] = actors[k]; 

     return clsActors; 
    } 
} 

Tuttavia, sto ottenendo un errore: "- operando incompatibile tipi booleano e Classe "

'attore' viene esteso dai miei sprite, dicono Uccello, eroe, ecc L'idea è, per esempio, per ottenere un elenco di tutte Uccelli sullo scenario in un dato momento per alcuni calcoli.

Qualche idea di cosa sta succedendo qui? Come testare se un dato oggetto è un'istanza di una data classe?

risposta

26
import java.util.Arrays; 

public class Main 
{ 
    static class Actor {} 
    static class Frog extends Actor {@Override public String toString() {return "I'm a frog";}} 
    static class Lizard extends Actor {@Override public String toString() {return "I'm a lizard";}} 

     private static Actor[] actors;   

     public static Actor[] getActors(Class<?> cls) { 
      //Count actors corresponding to class cls 
      int cnt = 0;  
      for (int i = 0; i<actors.length; i++) 
       if (cls.isInstance(actors[i])) cnt++; 

      //Build a new array; 
      Actor[] clsActors = new Actor[cnt]; 

      //Fill it 
      for (int j = 0, k=0; j<cnt; k++) 
        if (cls.isInstance(actors[k])) 
        clsActors[j++] = actors[k]; 

      return clsActors; 
     } 

    public static void main(String[] args) 
    { 
      actors = new Actor[] {new Frog(), new Lizard()}; 
      System.out.println(Arrays.toString(getActors(Frog.class))); 
    } 
} 

uscita:

[I'm a frog] 

Edit: la versione più elegante di getActors() utilizzando un elenco:

public static Actor[] getActors(Class<?> cls) { 
     LinkedList<Actor> chosenActors = new LinkedList<Actor>();   
     for(Actor actor: actors) if(cls.isInstance(actor)) chosenActors.add(actor);       
     return chosenActors.toArray(new Actor[0]); 
    } 
+1

Grazie mille per aver trovato il tempo di scrivere un esempio. –

+0

Prego! Se si utilizza questo esempio nel codice di produzione, tuttavia, penserei di utilizzare un elenco come tipo di ritorno o variabile temporanea perché è facile fare errori con gli indici del ciclo. –

+0

Sembra davvero più elegante usando le collezioni come dici tu, in realtà l'intera meccanica di Scenario ha funzionato usando le raccolte prima. * L'ho reso brutto *, perché le Collezioni assegnano roba (Iterator) e ho bisogno di questo array di attori per un ciclo di rendering. Ho finito di implementarlo ormai e mi sono sbarazzato di tonnellate di eventi GC_FOR_MALLOC. È un peccato perché il codice ha un aspetto magnifico usando ArrayLists ... (Non l'ho menzionato prima, ma questa è un'app per Android, così mirata ai dispositivi con specifiche basse) –

6

Prova questa:

cls.isInstance(yourObject) 

invece di utilizzare l'operatore instanceof, che può essere usato solo se si conosce la classe al momento della compilazione.

+0

Grazie mille! , qualche idea sull'impatto nelle prestazioni dell'uso del metodo isInstance? –

+0

Non sarà più lento di 'instanceof', molto probabilmente. –

3

instanceof può essere utilizzato solo con valori letterali di classe. È necessario utilizzare Class.isInstance(), cioè

if (cls.isInstance(actors[k])) 
Problemi correlati