检查泛型java中的引用类型

时间:2016-09-27 07:04:11

标签: java generics types reference instanceof

我目前正在使用java(基于回合制的RPG)构建游戏,并且在库存UI中遇到问题。也许我的问题是众所周知的或有一个简单的解决方案,但从未接受任何培训,我仍然会问这个问题。

在选择项目后显示库存时,我会检查该项目是否实现SpecificItemWorker界面,即对必须传递到GameObject的特定takeAction()的行为进行操作方法。在选择必须传递的对象时,我会显示所有可能的候选对象供用户选择。例如,假设用户选择一个UpgradeParchment作用于任何实现Upgradable接口的对象。在这里,我发起ItemSelector,显示实施Upgradable的广告资源中的所有项目。但是对于不同的类,对象需要实现以便成为可能的候选者的接口将有所不同。(注意,一些对象作用于游戏环境而不是特定对象,但我们在此不考虑这种情况。 )。现在不是硬编码switch case语句中可能的接口,我希望它是动态的。我试图使用泛型,但它不允许检查对象是否是instanceof Type参数。 以下代码给出了编译错误:

package ui;

import objects.Collectable;

public class ItemSelector<T> {
    public void test(Collectable ob) {
        if (ob instanceof T) {// compile error
            // do work
        }
    }
}

有谁知道如何实现这一目标?感谢您的帮助。

寻找快速回复, 感谢。

编辑: testAction()方法中的参数类型为Collectable,与我的库存类一样,只有Collectable个对象的列表。同样,在我的测试方法中,我更新了类型。虽然这是一个小小的改动,但不便之处。Collectable也是一个界面。

2 个答案:

答案 0 :(得分:1)

由于运行时类型擦除,您需要向类中提供所谓的类型标记

public class ItemSelector<T> {
    private final Class<T> clazz;
    public ItemSelector(Class<T> clazz) {
        this.clazz = clazz;
    }

    public void test(GameObject ob) {
        if (clazz.isInstance(ob)) {// use token to check type
            // do work
        }
    }
}

这需要将一个类对象传递给构造函数,通常是通过传递一个类文字,例如MyClass.class

答案 1 :(得分:0)

有一种方法可以使用class.getTypeName()来检查类型。

我假设SpecificItemWorker是一个游戏对象,如代码所示。

package stackoverflow.question39718130;

public class SpecificItemWorker extends GameObject {
}
package stackoverflow.question39718130;

public class ItemSelector<T> {

    private T t;

    public ItemSelector(final T t) {
        this.t = t;
    }

    public T getT() {
        return t;
    }

    public void test(final GameObject ob) {
        /*if (ob instanceof T) {// compile error
            // do work
        }*/

        if (t.getClass().getTypeName() == ob.getClass().getTypeName()) {
            System.out.println("Grab item.");
        } else {
            System.err.println("No item found.");
        }
    }
}

有一个测试示例可以传递GameObject

package stackoverflow.question39718130;

public class GameObjectTest {

    public static void main(final String[] args) {
        specificItemWorkerTest();
    }

    public static void specificItemWorkerTest() {
        final GameObject specificItemWorker = new SpecificItemWorker();

        final ItemSelector<GameObject> selector = new ItemSelector<>(specificItemWorker);
        selector.test(specificItemWorker);
    }
}

我希望我能用SpecificItemWorker理解你。如果这符合您的解决方案,请告诉我。