The compiler implicitly adds super() in A and B constructors, but why does the compiler really instantiates class A? This seems to be a performance hit in deep inheritance structures. Why wouldn't it be enough to collect the source one needs for an instance of B and just create b (without really executing the A constructor)?
Probably the best way to imagine what's happening is to think of a derived class as a shell around its parent class.
Mind this isn't strictly what happens, but it's a decent visualisation. To have access to the parent class methods and members an instance of the parent needs to exist, embedded as it were in the child (rather the reverse from a baby in the womb, more like old canibal tribes eating their parents' brains when the parents died to prevent their knowledge and souls from being lost).
Joined: Apr 12, 2006
My thought was why the compiler doesn't do something like a macro replacement (at compile time, of course). The compiler is able to see how many legs the ant has (to stay in the example above), but at runtime there's no compiler around if you create new objects.
The compiler is free to do static optimization. It should of course not be something that you can functionally detect, so I'm wondering what's bothering you? Even if B's constructor calls A's, the overhead is too low to worry about.
There is no emoticon for what I am feeling!
Joined: Apr 12, 2006
I stumbled upon this because I found an article dealing with performance issues regarding exception handling. Since the exception handling classes all have a minimum inheritance of three it can be worth sometimes to take a closer look. This reminded me about some kind of comparison between C++ and Java, and of of C++ pros was that it has a flat inheritance structure in comparison to Java (and I couldn't really see this as an advantage per se).
Don't forget that Java, unlike C++, uses runtime linkage. When Insect is compiled from the classes above, Animal has a trivial constructor, so it could indeed be optimized away. But Java allows you to edit and recompile Animal without touching Insect. If Animal's constructor becomes non-trivial, you of course want Insect to get the new code (if you disagree, imagine that "Animal" is HttpServlet or JComponent...) So this kind of optimization (i.e., constructor inlining) is not allowed.
In any case, the "overhead" of calling a superclass constructor is tiny compared to the fairly enormous overhead of creating a stack trace. Throwing an exception is an expensive operation, no matter what.
Originally posted by Ernest Friedman-Hill: So this kind of optimization (i.e., constructor inlining) is not allowed.
It's not allowed at compile time. It *is* allowed at runtime - and in fact, the modern Hot Spot Engine might well be able to do so, as far as I know.
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Jeroen T Wenting
Joined: Apr 21, 2006
probably, but the fact that it's not allowed compile time (and because a class can be replaced after compiling with another version that has the same signature without the need to recompile dependent classes) means that a Java compiler can't explicitly embed the functionality of one class inside another. If a parent class has a method "x" a C++ compiler could take that field and put it literally inside a child of that class. In Java "x" might well change in the parent after the child was compared, so that way is closed.