• Post Reply Bookmark Topic Watch Topic
  • New Topic

Why does inheritance work like this when it comes to constructors?  RSS feed

 
Mike Himstead
Ranch Hand
Posts: 178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 3742
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ?
 
Jeroen T Wenting
Ranch Hand
Posts: 1847
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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).
 
Mike Himstead
Ranch Hand
Posts: 178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 1780
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Mike Himstead
Ranch Hand
Posts: 178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Mike Himstead
Ranch Hand
Posts: 178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay, I think I got the picture, thanks to everyone.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Jeroen T Wenting
Ranch Hand
Posts: 1847
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!