So what's going on here? The C++ version correctly calls A::getResource()
because those who designed C++ were smart enough to know that polymorphic function calls in constructors is bad news.
The Java version, however, incorrectly performs a polymorphic function call and invokes B::getResource()
- however, since A has not finished being constructed, B hasn't even started
being constructed yet, resulting in a huge problem.
But surely there's a way in Java to force it to perform a static function call instead of a polymorphic one, right?
Wrong. There isn't. The designers of Java decided that constructors could only
perform polymorphic function calls. What's that? You think you're safe if you only call private methods? You're wrong - inner classes can extend their outer classes and can override private methods.
The chance of this actually happening is pretty low, especially amongst good programmers (even ones who don't know of this quirk), but it's still incredibly dangerous.
My question is: Why on earth would the designers of Java think this was OK? I know it must have been a really old decision that can't be changed unless we jump from Java 1.x to Java 2.x, but that doesn't excuse the fact that the decision was made.
What's worse is that they could easily
add a simple syntax to allow constructors to statically call methods rather than polymorphically, and yet they haven't and have no plans to (at least not in Java 8, which by the way won't be having lambdas after all).
This is beyond frustrating to me. The simple fact that it's not possible to port the C++ version to Java without changing the interface is unacceptable to me.
Yes, I'm angry. At least this issue doesn't affect me currently or I'd be even angrier. And yes I'm most definitely overreacting ;)