I want to know how to identify subclasses at run time in java. In my program I am calling a method that returns a superclass object. The object can be an instance of a开发者_如何学Pythonny one of its sub-classes. I want to know the object is instance of which sub-class at run-time so that I can cast it to that subclass and access subclass methods. Can anyone help me in this?
Thanks
You can just use instanceof to check if an object is an instance of a particular class. eg:
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.meow();
} else if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
}
However, overuse of instanceof (or down-casting, for that matter) is generally considered to be a sign of poor design. It's better to instead make use of polymorphism. For example, have a (possibly abstract) "speak" method in Animal, and then each subclass would have a different implementation. The above code would then be replaced with a call to speak:
animal.speak();
Call getClass() on the object to access a Class object that tells you the object's actual type. You can then compare this to the ".class" static member of any class.
if (obj.getClass().equals(Foo.class)) { ... }
However many people would say what you're suggesting is bad design. Make sure it's necessary and consider alternatives. It's often necessary in implementing methods like equals().
Use instanceof
operator. Like this
Superclass aSup = ...;
if(aSup instanceof Subclass) {
Subclass aSub = (Subclass) aSup;
aSub.subclass_method(...);
}
Note, instanceof is true if the object is a type assignable to the class specified. The following (as described above) would work
if (o instanceof Cat.class) {
// ..
} else if (o instanceof Dog.class) {
// ..
} else {
throw IllegalArgumentException("Unexpected type");
}
However if you introduce a new subclass of cat, e.g. Tiger then the first clause above would be triggered unless you updated all the code that did this.
You may want to search for Double Dispatch for a potential way of having to do the above, of course without knowing teh problem you are trying to solve this may not be applicable.
You can use 'instanceof' operator and direct Class objects comparison as was mentioned above.
However, if you want to modify the code in order to avoid explicit checks I see two ways to go:
- GoF Visitor pattern;
- encapsulate class-specific processing logic, i.e. create something like this:
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);
}
You can use the instanceof
operator to test the type an object and then cast.
精彩评论