参数 instanceof Class<?> 的含义是什么?

24

我正在尝试编写一个方法,以返回与其作为参数传递的类匹配的所有对象:

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

然而,我遇到了一个错误:"- 不兼容的操作数类型:boolean和Class<capture#1-of?extends Scenario>"

'Actor' 被我的精灵(例如Bird、Hero等)继承。 我的想法是,在某个时间点上获取场景中所有Birds的列表以进行某些计算。

有什么想法这里发生了什么?如何测试给定对象是否是给定类的实例?

3个回答

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

输出:

[I'm a frog]

编辑:使用列表(List)更优雅的方式获取演员(getActors())方法:

    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
非常感谢您抽出时间编写示例。 - Bigger
不客气!如果您在生产代码中使用此示例,我建议考虑使用列表作为返回类型或临时变量,因为循环索引容易出错。 - Konrad Höffner
确实,使用集合看起来更优雅,实际上整个场景机制之前就是使用集合完成的。但是我把它搞得很丑,因为集合会分配一些东西(迭代器),而我需要这些演员数组用于渲染循环。现在我已经完成了实现,并且消除了大量的GC_FOR_MALLOC事件。很遗憾,因为使用ArrayLists时代码看起来非常棒...(我之前没有提到,但这是一个针对低规格设备的Android应用程序) - Bigger

15

试一下这个:

cls.isInstance(yourObject)

不要使用 instanceof 运算符,因为它只能在编译时知道类的情况下使用。


非常感谢!使用isInstance方法对性能有什么影响的想法吗? - Bigger
很可能不会比 instanceof 慢。 - Costi Ciudatu

6

instanceof只能与类字面量一起使用。您需要使用Class.isInstance(),即

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接