When a class is instantiated, the subsequent object is actually an instance of the most derived class in the class hierarchy. This means that even if a class is referenced by a superclass reference, it should still have the behavior and state of the subclass available to it at run time. For example, consider this code:
1. public class Base {2. }3. 4. public class Derived extends Base {5. public String getSquare () {6. return "Result";7. }8. }
The method getResult() is defined in the derived class. However, suppose that you had a reference to an object of type Base whose runtime class was Derived:
Base myObject = new Derived();
The method getResult() can be called using the reference myObject, but not directly. If you try to execute myObject.getResult(), you will get an exception since myMethod() does not exist in the class Base. However, Java’s reflection mechanism lets you call the subclass method:
1. Base b = new Derived();2. 3. // Call the method on the derived class4. Class baseClass = b.getClass();5. Method m = baseClass.getMethod("getResult", new Class {});6. String result = baseClass.invoke(m, new Object[] {});7. System.out.println(result);
The subclass is instantiated on Line 1. On Line 4, the runtime class of the object b is obtained, and is used to get the “getResult()” method on Line 5. Finally, the method is invoked and printed out on Lines 6-7.