Good question!
This one's pretty tricky, but I think I've got it figure out. The key is that empty method in the class XTC. This gets into the nit-picky details about how the correct method is found to be executed. You can read pages on this topic in the JLS,
§15.12.4 Runtime Evaluation of Method Invocation. However, I'll try to clear this up here.
Here's a snippet from the JLS,
§15.12.4.4 Locate Method to Invoke:
Let X be the compile-time type of the target reference of the method invocation.
1. If class S contains a declaration for a non-abstract method named m with the same descriptor (same number of parameters, the same parameter types, and the same return type) required by the method invocation as determined at compile time (�15.12.3), then:
- If the invocation mode is super or interface, then this is the method to be invoked, and the procedure terminates.
- If the invocation mode is virtual, and the declaration in S overrides (�8.4.6.1) X.m, then the method declared in S is the method to be invoked, and the procedure terminates.
2. Otherwise, if S has a superclass, this same lookup procedure is performed recursively using the direct superclass of S in place of S; the method to be invoked is the result of the recursive invocation of this lookup procedure.
What happens is the JVM starts with the compile-time type of the target object. The target object is the object referenced by x. The compile-time type of x is XTC, even though it's run-time type is ZZY.
The JVM first looks in the the compile-time class (XTC) for a matching method. It finds a method that matches (that's the empty method up there).
Next, the JVM has to determine if this is the method that should be executed or if this method has been overridden in the subclass. It has to do this check because the run-time type of x is ZZY. Indeed, there is a method defined in ZZY that overrides this method. Remember, when you override a method, the parameters have to match
exactly.
Therefore, the overriding method (the one that take an int, not a char) is invoked by the JVM. It would seem that the other method is a better match, but due to the overridden method, the one that takes an int is called.
Now, if you remove that empty method from the class XTC, you'll see that the method that takes a char is invoked, as it is the best match based on the parameters passed.
I hope that helps clear things up.
Where did you find that question? That one is pretty rough.
Corey