In C++ you have a choice of how to do composition.
You can either store an object directly within another object. (1)
1 2
|
class A {};
class B { A obj; };
|
Or you could use a reference, pointer or smart pointer to refer to an object stored elsewhere. (2)
1 2
|
class A {};
class B { A* ptr = new A; };
|
If you use #1 the type of the inner object B::obj is known at compile time. There is no way it could be anything other than A.
If you use #2 the type of the object pointed to by A::ptr is not fixed at compile time. If there are other classes that inherits from A you could at runtime decide which of them the pointer should point to. If A has a virtual function that can be overriden by the derived classes it would not be known at compile time which version of a function that should be called. Instead the decision would have to be based on the dynamic type of the object at runtime. This is what "dynamic binding" refers to.
In Java you cannot store objects within objects. You always have to use a
reference variable when referring to an object. This means only #2 is possible in Java, and because all non-static methods are virtual (i.e. they can be overriden) they have to be resolved at runtime (=dynamic binding).
I want to point out that I'm not totally sure what kind of optimizations is allowed in C++, and especially in Java. There might be situations where a clever compiler can (and is allowed to) resolve a virtual function call at compile time even though it's called through a pointer/reference variable.