Why does inheritance work like this when it comes to constructors?
Mike Himstead
Ranch Hand
Joined: Apr 12, 2006
Posts: 178
posted
0
Fist, some code:
Output is: In A constructor In B constructor 4
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)?
Joanne Neal
Rancher
Joined: Aug 05, 2005
Posts: 3011
9
posted
0
Because constructors are used to initialise a class. Consider the class hierarchy
How many legs would an ant have if the Ant constructor didn't call the Insect constructor ?
Joanne
Jeroen T Wenting
Ranch Hand
Joined: Apr 21, 2006
Posts: 1847
posted
0
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).
42
Mike Himstead
Ranch Hand
Joined: Apr 12, 2006
Posts: 178
posted
0
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.
Jeff Albertson
Ranch Hand
Joined: Sep 16, 2005
Posts: 1780
posted
0
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!
Mike Himstead
Ranch Hand
Joined: Apr 12, 2006
Posts: 178
posted
0
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).
That being said, I never bothered before.
Ernest Friedman-Hill
author and iconoclast
Marshal
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.
Okay, I think I got the picture, thanks to everyone.
Ilja Preuss
author
Sheriff
Joined: Jul 11, 2001
Posts: 14112
posted
0
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
Ranch Hand
Joined: Apr 21, 2006
Posts: 1847
posted
0
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.