在运行时识别子类

时间:2009-11-02 06:41:41

标签: java

我想知道如何在java中运行时识别子类。在我的程序中,我正在调用一个返回超类对象的方法。该对象可以是其任何一个子类的实例。我想知道对象是运行时哪个子类的实例,以便我可以将它转换为该子类并访问子类方法。任何人都可以帮助我吗?

由于

6 个答案:

答案 0 :(得分:7)

您可以使用instanceof来检查对象是否是特定类的实例。例如:

if (animal instanceof Cat) {
    Cat cat = (Cat) animal;
    cat.meow();
} else if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();
}

但是,过度使用instanceof(或者说是向下铸造)通常被认为是设计不佳的标志。最好是利用多态性。例如,在Animal中有一个(可能是抽象的)“speak”方法,然后每个子类将有不同的实现。然后,上面的代码将替换为发言:

animal.speak();

答案 1 :(得分:4)

在对象上调用getClass()以访问一个Class对象,该对象告诉您对象的实际类型。然后,您可以将其与任何类的“.class”静态成员进行比较。

if (obj.getClass().equals(Foo.class)) { ... }

然而,很多人会说你的建议是糟糕的设计。确保有必要并考虑替代方案。实现像equals()这样的方法通常是必要的。

答案 2 :(得分:1)

使用instanceof运算符。喜欢这个

Superclass aSup = ...;
if(aSup instanceof Subclass) {
    Subclass aSub = (Subclass) aSup;
    aSub.subclass_method(...);
}

答案 3 :(得分:1)

注意,如果对象是可分配给的对象,则instanceof为true 指定的类。以下(如上所述)将起作用

if (o instanceof Cat.class) {
  // ..
} else if (o instanceof Dog.class) {
  // ..
} else {
  throw IllegalArgumentException("Unexpected type");
}

但是,如果你引入一个新的cat子类,例如虎然后 除非您更新了所有代码,否则将触发上面的第一个子句 这样做了。

您可能希望搜索Double Dispatch以寻找潜在的方式 必须做上述事情,当然不知道你是谁的问题 试图解决这个问题可能不适用。

答案 4 :(得分:1)

如上所述,您可以使用'instanceof'运算符并直接进行Class对象比较。

但是,如果您想修改代码以避免明确检查,我会看到两种方法:


interface Handler<T> {
    void handle(T object);
}

Map<Class<?>, Handler<?>> HANDLERS = /* init handlers mappings */;

...

public void process(Object obj) {
    Handler<?> handler = HANDLERS.get(obj.getClass());
    if (handler == null) {
        throw new IllegalStateException("bla-bla-bla, no handler is registered for class " + obj.getClass());
    }
    handler.handle(obj);
}

答案 5 :(得分:0)

您可以使用instanceof运算符测试对象的类型,然后进行转换。