instanceof Class<?> parameter

22,652

Solution 1

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

Output:

[I'm a frog]

Edit: More elegant version of getActors() using a List:

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

Solution 2

Try this:

cls.isInstance(yourObject)

instead of using the instanceof operator, which can only be used if you know the class at compile time.

Solution 3

instanceof can only be used with class literals. You need to use Class.isInstance(), i.e

if (cls.isInstance(actors[k]))
Share:
22,652

Related videos on Youtube

Bigger
Author by

Bigger

Updated on July 11, 2022

Comments

  • Bigger
    Bigger almost 2 years

    I'm trying to write a method to return all objects that match the class it gets as a parameter:

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

    However, I'm getting an error: "- Incompatible operand types boolean and Class<capture#1-of ? extends Scenario>"

    'Actor' is extended by my sprites, say Bird, Hero, etc. The idea is, for example, to get a list of all Birds on the Scenario at a given time for some calculations.

    Any idea what's going on here? How to test if a given object is an instance of a given class?

  • Bigger
    Bigger over 11 years
    Thank you very much!, any idea about the impact in performance of the usage of the isInstance method?
  • Costi Ciudatu
    Costi Ciudatu over 11 years
    It won't be slower than instanceof, most likely.
  • Bigger
    Bigger over 11 years
    Thank you very much for taking the time to write an example.
  • Konrad Höffner
    Konrad Höffner over 11 years
    You're welcome! If you use this example in production code I would however think about using a list as a return type or temporary variable because it's easy to make mistakes with the loop indices.
  • Bigger
    Bigger over 11 years
    It indeed looks more elegant using collections as you say, actually the whole Scenario mechanic worked using collections before. I made it ugly, because Collections allocate stuff (Iterators) and I need this actor arrays for a render loop. I finished implementing it by now and I got rid of tons of GC_FOR_MALLOC events. It's a pity because the code used to look wonderful using ArrayLists... (I didn't mention it before but this is an android app, so targeted to low specs devices)