This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
The output is : Printing myTest in Test class Printing myStat in MyTest class Can someone explain me why ? Thanks in advance. Edited by Corey McGlone: Added Code Tags [ May 09, 2003: Message edited by: Corey McGlone ]
Hi Priya, Well to understand one thing is that when dealing with static methods in heritance is that , which method myStat() will be called is dependent on the reference you use. In the above code since the reference mt is of type MyTest when the code is executed java will execute the method at the MyTest and not of the object which is Test(). So to say if you change the above code and use Test mt = new Test(); the output will be Printing myTest in Test class Printing myStat in Test class Hope it helps if not let me know will explain in further.
The important thing to notice is that the method myTest is an instance method while the method myStat is a static method - this is a key difference. The result of this difference is that, in one case, we have a overridden method (which means dynamic method lookup will be used) and, in the other case, we have a hidden method. You can take a look at the JLS, §8.4.6 Inheritance, Overriding, and Hiding for all sorts of great information on overriding and hiding methods. However, to go on answering your question, we have to next explore how the JVM determines which method to invoke. Again, I'll refer to the JLS. You can take a look at §15.12 Method Invocation Expressions for gobs of information, but I'll try to highlight some of the key pieces of information for you. In §15.12.4 Runtime Evaluation of Method Invocation, it reads:
At run time, method invocation requires five steps. First, a target reference may be computed...
So, what does that mean? That means that the JVM is going to try to determine which object the method should be invoked on. Let's read on a bit to determine how this is done. (Just to help you read through the JLS, we're using the second production for MethodInvocation, which invovled a primary, mt, and a method name, myTest or myStat.) Let's first consider the process gone through when invoking the static method, myStat. The JLS states:
If the invocation mode is static, then there is no target reference. The expression Primary is evaluated, but the result is then discarded.
Did you get that? The JVM will evaluate the Primary (mt), but it then throws it away? Why would it do such a thing? Well, in this case, we're invoking a static method, myStat. When we're invoking a static method, the JVM doesn't care what the run-time type of a variable is. Within a static context, the method will be invoked on the variable's compile-time type class. That means that, if you have a variable of type MyTest and you invoke myStat on it, the JVM will invoke MyTest.myStat, regardless of what type of object your variable refers to at runtime. The JLS states, in §184.108.40.206 Locate Method to Invoke:
If the invocation mode is static, no target reference is needed and overriding is not allowed. Method m of class T is the one to be invoked.
In fact, you could even have a variable that refers to null and invoke a static method on it without any problem. You see, when invoking a static method, the JVM cares only about the type of the variable the method is being invoked on, not the type of the object is actually refers to. Now, to contrast, that, let's look at what happens when we invoke an instance method, such as myTest. Looking back at the JLS, we see:
Otherwise, the expression Primary is evaluated and the result is used as the target reference.
Okay, so now we're going to use mt as a target reference. Let's see what the JVM is going to do with it... This is what the JLS says about finding the correct method to invoke:
The dynamic method lookup uses the following procedure to search class S, and then the superclasses of class S, as necessary, for method m. 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 (�220.127.116.11) 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.
I tried to highlight the important parts of that, but let me try to summarize. What will happen is that the JVM will take the target reference, mt, and look into the object referenced by that variable for a method that matches the signature of the method that was invoked. If it finds one, that method will be invoked. If not, it will scan the parent class for the named mathod. If it doesn't find one there, it will again scan the parent class, and so on, until it finds the method it is looking for.
I realize I got into quite a bit of detail about how this mechanism operates and I hope I didn't lose you going through the JLS. The short of the matter is that dynamic binding is only used for overridden methods and static methods can not be overridden. Therefore dynamic binding is not used in that case. If you're still confused (or more confused than before :roll: ) after reading my explanation, let me know. I'll try to be more clear next time. Corey