2012-11-09 7 views
14

Próbuję napisać metodę, aby powrócić wszystkie obiekty, które pasują do klasy to dostaje jako parametr:instancją klasy <?> parametr

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; 
    } 
} 

Jednak dostaję błąd: „- Incompatible operand typy logiczna i klasy

«Aktor»zostaje przedłużony o moich duszków, powiedzmy Ptak, bohater, itp pomysł jest, na przykład, aby uzyskać listę wszystkich Birds on the Scenario w danym czasie dla niektórych obliczeń.

Czy masz pojęcie, co się tutaj dzieje? Jak sprawdzić, czy dany obiekt jest instancją danej klasy?

Odpowiedz

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))); 
    } 
} 

wyjściowa:

[I'm a frog] 

Edycja: bardziej elegancka wersja getActors() na podstawie listy:

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

Dziękuję bardzo za poświęcenie czasu na napisanie przykładu. –

+0

Nie ma za co! Jeśli użyjesz tego przykładu w kodzie produkcyjnym, pomyślałbym o używaniu listy jako typu zwrotnego lub zmiennej tymczasowej, ponieważ łatwo jest popełniać błędy za pomocą indeksów pętli. –

+0

Rzeczywiście wygląda bardziej elegancko przy użyciu kolekcji, jak mówisz, w rzeczywistości cały mechanik scenariusz pracował wcześniej przy użyciu kolekcji. * Zrobiłem to brzydko *, ponieważ Kolekcje alokują rzeczy (Iteratory) i potrzebuję tych tablic aktorów dla pętli renderowania. Skończyłem już to wdrażanie i pozbyłem się ton zdarzeń GC_FOR_MALLOC. Szkoda, bo kod świetnie wyglądał przy użyciu ArrayLists ... (Nie wspominałem o tym wcześniej, ale jest to aplikacja dla systemu Android, która jest przeznaczona dla urządzeń o niskiej specyfikacji) –

6

Spróbuj:

cls.isInstance(yourObject) 

zamiast za pomocą operatora instanceof, który może być stosowany tylko wtedy, gdy wiesz, że klasę w czasie kompilacji.

+0

Dziękuję bardzo! , jakąkolwiek koncepcję dotyczącą wpływu na wydajność korzystania z metody isInstance? –

+0

Prawdopodobnie nie będzie wolniejszy od 'instanceof'. –

3

instanceof może być używany tylko z literałami klasy. Trzeba użyć Class.isInstance(), tj

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