+6  A: 

You are confusing dynamic invocation with dynamic binding..

The first one allows the type checker to accept programs in which you are not sure if a method will be present on an object at run-time, while dynamic binding just chooses the right implementation according to the runtime type of the object but maintaining the statically type checking.

What does it mean?

It means that in your example, Java will call the implementation on object B because the runtime type of the objA variable is B; and it will compile because it knows that a B is a A so the method invocation won't fail at runtime (objA will have a F implementation for sure).

With dynamic invocation instead it won't check at compile time that the type of the object on which you are calling F contains that method, of course it will raise an exception if during execution the method won't be available on specified object.

Just for trivia: the invokedynamic feature will be added with Java7 because many scripting languages have been written to work on top of JVM and the lack of a dynamic invocation feature forced the developers of these languages to add a middle layer between the script and the real JVM that cares about dynamic invocation using the reflection. Of course this approach causes a lot of overhead (think about Grovvy's MetaClass), that's why Sun decided to give them a help..

Jack
+1 for the trivia
Mihir Mathuria
A: 

In your example the correct method is called because polymorphically the instance of B appears like an instance of A. The method can be located by examining the runtime type of the object; that is, B; as opposed to the compile-time type of the object reference, A. The other important part is the signature of method - these must always match (polymorphically of course).

This differs from dynamic languages because in those there is essentially no compile-time for the object - and everything must be resolved at runtime.

Steven Mackenzie
+1  A: 

In fact, what you're missing is that this is the part of 'invokevirtual' which is explained in the article.

You're simply overriding the method and that uses a virtual method table to invoke the correct method.

Sebastian P.R. Gingter
A: 

I wouldn't call your example "dynamic", rather virtual. Because at compile time the method name and signature is known (and its existence is checked by the compiler). The only that is resolved at runtime is the concrete implementation to be used for that method.

A more proper example of "dynamic" method invocation would involve reflection, (see the Method class ). In that way, methods whose existence are unkown at compile type can be invoked in runtime (this is extensively used by frameworks, not so much by application code).

The article you mention seems a little misleading in that respect. But it's true that the signature of the methods you explicitly call must be known/checked in compile time, and so, in that sense, Java is not dynamic.

leonbloy