我想知道如何在java中运行时识别子类。在我的程序中,我正在调用一个返回超类对象的方法。该对象可以是其任何一个子类的实例。我想知道对象是运行时哪个子类的实例,以便我可以将它转换为该子类并访问子类方法。任何人都可以帮助我吗?
由于
答案 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
运算符测试对象的类型,然后进行转换。