Java - Virtual Methods
Asked Answered
P

3

17

How does virtual functions work behind the scenes in Inheritance ? Does the compiler treat virtual functions specially ?

Pinprick answered 21/3, 2010 at 6:14 Comment(0)
N
13

Yes, virtual methods are treated differently by the compiler and the runtime. The JVM specifically utilizes a virtual method table for virtual method dispatch:

An object's dispatch table will contain the addresses of the object's dynamically bound methods. Method calls are performed by fetching the method's address from the object's dispatch table. The dispatch table is the same for all objects belonging to the same class, and is therefore typically shared between them. Objects belonging to type-compatible classes (for example siblings in an inheritance hierarchy) will have dispatch tables with the same layout: the address of a given method will appear at the same offset for all type-compatible classes. Thus, fetching the method's address from a given dispatch table offset will get the method corresponding to the object's actual class.

Nunes answered 21/3, 2010 at 6:18 Comment(0)
R
38

All methods in java are virtual by default. That means that any method can be overridden when used in inheritance, unless that method is declared as final or static.

Redbird answered 21/3, 2010 at 6:19 Comment(5)
Non-static (instance) methods are always virtual. Static (class) methods are never virtual. You are right in that a virtual method that is declared final cannot not be overridden in a derived class.Desulphurize
don't you forget Constructor.Uncinate
@JerryLiu That depends on if you consider the constructor a method or not. I believe the community still does not agree on that topic.Redbird
According to the oracle documentation, not only are contructors not a method, they are not even a member: "...Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass..."Meeting
@Dean P Oracle documentation may say whatever, but java.lang.reflect.Constructor implements java.lang.reflect.Member, as well as other "true members" - Field, MethodPlaybill
I
15

'Virtual' is a C++ term. There are no virtual methods in Java. There are ordinary methods, which are runtime-polymorphic, and static or final methods, which aren't.

Intervenient answered 21/3, 2010 at 23:53 Comment(10)
I didn't downvote however I think the statement "all methods in Java are virtual by default" is better. While there is no specific "virtual" modifier in Java the underlying concept is still the same. Claiming that there are no virtual methods is a bit misleading IMHOGlisten
@Glisten But your version isn't true. Static methods aren't virtual in any sense, or runtime-polymorphic either. My version captures that: yours doesn't. And Ockham's razor dictates that you don't multiply concepts needlessly. There is no need for the word 'virtual' when discussing Java, any more than there is in the language itself.Intervenient
@EJP Your answer is helpful in understanding Java's conceptual underpinnings. However, at a low-level it's not possible to ignore the concept of a virtual method, since it's implemented under the hood by the JVM and DVM (and explicitly declared in their respective bytecodes). So, once you go in a bit deeper, knowledge of what virtual functions are is really necessary.Messier
@Messier I disagree. Since the Java default is to make the method runtime-polymorphic unless you specify otherwise, there is no need to import the term 'virtual' from other languages where it may be needed.Intervenient
The characterization of methods as either ordinary, static or final could be misunderstood. For a final method, the instance's class's implementation is invoked when the method is called on a value typed as the base class, just like other non-static methods.Desulphurize
@TomBlodget I haven't said anything about this matter one way or the other, but it seems to me that the only misunderstanding here is yours. For a final method, the most-derived implementation is called. The instance class may not have that implementation itself. It may not be in the instance class itself.Intervenient
Good point. I was trying avoid the word "virtual" by describing what it means. You've brought out a more accurate description. Anyway, methods in Java, in one aspect, are either virtual or static. There are no other categories in that aspect. Or, put another way, a method is virtual if and only if it is an instance method.Desulphurize
@TomBlodget That's not correct either. Methods in Java are 'in one aspect, virtual, final, or static.' But I intensely dislike importing the foreign term virtual into Java discussions.Intervenient
Java absolutely does use a virtual method table in the JVM, which is even implemented by a dispatcher called invokevirtual. It doesn't get any clearer than that: using the term virtual is the most correct and accurate term to use to refer to non-final, non-static methods in Java. In other words, all methods in Java are virtual by default ("default" meaning you haven't used the static or final keywords). The term isn't being "imported", it is the correct term.Winterfeed
@Winterfeed Nobody has denied the existence of a 'virtual method table' or the existence of the opcode. The issue here is how to describe the language, not the implementation. 'All methods in Java are runtime-polymorphic by default' would be a correct formulation. 'Virtual' has no meaning in the JLS.Intervenient
N
13

Yes, virtual methods are treated differently by the compiler and the runtime. The JVM specifically utilizes a virtual method table for virtual method dispatch:

An object's dispatch table will contain the addresses of the object's dynamically bound methods. Method calls are performed by fetching the method's address from the object's dispatch table. The dispatch table is the same for all objects belonging to the same class, and is therefore typically shared between them. Objects belonging to type-compatible classes (for example siblings in an inheritance hierarchy) will have dispatch tables with the same layout: the address of a given method will appear at the same offset for all type-compatible classes. Thus, fetching the method's address from a given dispatch table offset will get the method corresponding to the object's actual class.

Nunes answered 21/3, 2010 at 6:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.