动态比较java中的类型

时间:2016-01-02 22:45:20

标签: java casting

我有一个Screen类,它是几种屏幕的基类,例如PauseScreen,MainScreen等。

我的课程中有一叠屏幕,我的游戏根据按钮按下/弹出屏幕。

但我需要从一个屏幕跳到另一个屏幕(弹出所有屏幕直到所需的屏幕)。

假设我有一个主屏幕,一个GameScreen和一个PauseScreen。我需要从PauseScreen转到MainScreen,(弹出PauseScreen和GameScreen)。

在java中首选的方法是什么?我可以在每个屏幕上存储一个id,但看起来不对。

编辑:这就是我想要实现的目标,我只是想知道是否有更好的方法不需要创建枚举(IIRC可以在运行时获取类的类型,但也许它我想做什么是不好的做法?)。

class X
{
    Stack< Screen > screens = new Stack< Screen >();

    void push( Screen s )
    {
        screens.push( s );
    }

    void pop()
    {
        screens.pop();
    }

    void popUntil( Screen.Type t )
    {
        // go through the list in reverse order
        while( screens.next().type != t )
            screens.pop();
    }
}

// other places in the code

app.popUntil( Screen.Type.MainScreen );
app.popUntil( Screen.Type.GameScreen );

4 个答案:

答案 0 :(得分:1)

使用instanceof运算符

Screen screen = stack.pop();
if (screen instanceof PauseScreen) {

}
else if (screen instanceof MainScreen) {

}
else if (screen instanceof GameScreen) {

}
else if (/*...*/) {
    //...
}
else {
    otherStack.push(screen);
}

答案 1 :(得分:1)

您可以使用instanceof运算符来实现此目的:

if(someObject instanceof SomeType)
{
    SomeType cast = (SomeType) someObject;
    //do stuff with cast
}

本教程中有关于此主题的部分:http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html

答案 2 :(得分:1)

这可能是Visitor pattern的好候选人。

public interface ScreenVisitor {
    void visitMain(MainScreen screen);
    void visitGame(GameScreen screen);
    void visitPause(PauseScreen screen);
}

public class VisitorForStuff implements ScreenVisitor {
    void visitMain(MainScreen screen) {
        // do stuff for MainScreen
     }
     // etc.
}

public abstract class Screen {
    ...
    public abstract void visit(ScreenVisitor visitor);
    ...
}

public class GameScreen extends Screen {       
    ...
    public void visit(ScreenVisitor visitor) {
        visitor.visitGame(this);
    }
    ...
}

...
Screen screen = stack.pop()
screen.visit(new VisitorForStuff());
...

访问者使用双重调度机制来允许类型安全的向下转换,而无需使用instanceof和cast。虽然在特定情况下使用instanceof没有太大区别,但它是一种非常灵活的模式 - 允许许多不同类型的Visitor实现 - 并且它通过编译时错误突出显示使用,因此当您创建新的时通过Screen的实现,您可以扩展Visitor界面并快速找到需要更新的所有位置,以便处理访问新类型的Screen。

答案 3 :(得分:1)

您可以使用.class运算符直接引用类,该运算符返回java.lang.Class个实例:

class X
{
    // ...

    void popUntil(Class<? extends Screen.Type> type)
    {
        // go through the list in reverse order
        while( screens.next().getClass() != type)
        {
            screens.pop();
        }
    }
}

x.popUntil(Screen.Type.MainScreen.class);
x.popUntil(Screen.Type.GameScreen.class);

请注意,可以使用引用相等(java.lang.Class==)而不是对象相等(!=方法)来比较equals的实例。但是,此实现仅检查实例的类型是否与给定参数完全相同。如果您想检查extendsimplements,可以使用java.lang.Class#isInstance(Object)方法:

while (!type.isInstance(screens.next()))
{
    screens.pop();
}