- Late Binding by Example
- Implications for Binary Compatibility
- Overloading and Overriding
- Deleting Overridden and Overloaded Methods
- Fields
- Conclusion
Implications for Binary Compatibility
So finding what method to use is as simple as matching strings and walking up the class inheritance tree. This fact has a number of implications that can help you understand the sorts of changes you can make while retaining binary compatibility.
It should be clear that you can reorder methods in the classsomething that you generally can't do with C++ programs. That's because C++ programs use numerical offsets, rather than the name, to determine what method implementation to use. That's a critical part of late binding. If Java used the offset of the method in the class, it would severely limit binary compatibility because even simple changes would require substantial recompilation.
NOTE
You might argue that the C++ way is faster than the Java way, since numerical offsets are faster to work with than string matching. This is true for the first time you load a class, but after that a Java just-in-time (JIT) compiler can work with numerical offsets rather than string matching. That's because the JIT doesn't have to worry about binary compatibility any more; the class isn't allowed to change once it has been loaded. So, at least for method invocation, there's no reason for a Java program to run any slower than a C++ program.
Another important implication is that the JVM looks up the class hierarchy at runtime, rather than just at compile time. We could alter the implementation of our Bordeaux class, for example:
class FrenchReds extends RedWine { // French wines are served a little warmer in general float temperature() { return 65; } } class Bordeaux extends FrenchReds { // But we're keeping the same temperature, just changing the // superclass float temperature() { return 64; } }
Even with the altered superclass hierarchy, you can continue to run the sample code without recompiling.