How can a derived class invoke private method of base class?

https://www.coolcoder.in/2011/08/how-can-derived-class-invoke-private.html
My question seems little weird but it made be think for a while when i went through a post on Java World. The author of the post Inheritence problem(a demo form Thing in java) asked a similar question what I mentioned in my title.
So now when you invoke main method in DerivedClass, it must print "Demo method from Base Class." But if invokevirtual would have been used, it would print "Demo method from Derived Class." Why? Because the virtual machine would choose the demoMethod() to call based on the actual class of the object, which is DerivedClass. So it will use DerivedClass's demoMethod(). On the other hand, with invokespecial the virtual machine will select the method based on the type of the reference, so BaseClass's version of demoMethod() will be invoked.
Feel free to share your thoughts on the post through comments.
Submit this post on reddit
So here is the exact code.
public class PrivateOverride { private void f() { System.out.println("private f()"); } public static void main(String[] args) { PrivateOverride po = new Derived(); po.f(); } } class Derived extends PrivateOverride { public void f() { System.out.println("public f()"); } }
So the output of this code as mentioned by the author of the code is "private f()". Now the very obvious question arises that how can po which is an object of Derived Class call a private method of PrivateOverride which is its base class.
So I just went through the byte code of the compiled version of the above class and got the invokespecial Opcode. This Opcode was enough to tell the reason why the actual output is obvious. So I will try to explain why it is so?
First we should know
What is invokespecial?
Instance methods normally are invoked with invokestatic, invokevirtual, invokespecial and invokeinterface.
After the release of Java 7, invokedynamic is too added to the above mentioned list.
Invokespecial is used in three situations in which an instance method must be invoked based on the type of the reference, not on the class of the object. The three situations are:
Invokespecial is used in three situations in which an instance method must be invoked based on the type of the reference, not on the class of the object. The three situations are:
- invocation of instance initialization (
) methods invocation of private methods invocation of methods using the super keyword
So now the question arises why invokespecial? We have other Opcode like invokevirtual which gets invoked for method on the basis of classtype rather than reference type. So lets discuss why invokespecial Opcode is used for private methods.
But we should know the difference between invokevirtual and invokespecial.
Invokespecial differs from invokevirtual primarily in that invokespecial selects a method based on the type of the reference rather than the class of the object. In other words, it does static binding instead of dynamic binding. In each of the three situations where invokespecial is used, dynamic binding wouldn't yield the desired result.
But we should know the difference between invokevirtual and invokespecial.
Invokespecial differs from invokevirtual primarily in that invokespecial selects a method based on the type of the reference rather than the class of the object. In other words, it does static binding instead of dynamic binding. In each of the three situations where invokespecial is used, dynamic binding wouldn't yield the desired result.
Here is an example that explains the reason more clearly
class BaseClass { private void demoMethod() { System.out.println("Demo method from Base class."); } void exampleMethod() { interestingMethod(); } } class DerivedClass extends Baseclass { void demoMethod() { System.out.println("Demo method from Derived class"); } public static void main(String args[]) { DerivedClass derived = new Subclass(); derived.exampleMethod(); } }
So now when you invoke main method in DerivedClass, it must print "Demo method from Base Class." But if invokevirtual would have been used, it would print "Demo method from Derived Class." Why? Because the virtual machine would choose the demoMethod() to call based on the actual class of the object, which is DerivedClass. So it will use DerivedClass's demoMethod(). On the other hand, with invokespecial the virtual machine will select the method based on the type of the reference, so BaseClass's version of demoMethod() will be invoked.
Feel free to share your thoughts on the post through comments.
References
http://www.javaworld.com/community/node/8089
http://www.artima.com/underthehood/invocationP.html
wonderful codes, checkout my blogs at
ReplyDeletehttp://www.definingwords.blogspot.com
http://www.sa-sports99.blogspot.com
feel free to leave a comment
Brilliant observation. Sharing via twitter.
ReplyDeleteI know this site gives quality based articles and other stuff,
ReplyDeleteis there any other site which offers these things in quality?
Feel free to visit my homepage: kitchen exhaust fans - ,