0

Java allows constructors of non-final classes to invoke any instance methods, even if those methods are abstract or non-final.

This is recognized as a bad practice (see., e.g., Effective Java 2nd Edition, Item 17), and isn't possible in C++ because of the defined constructor order.

My question is why this was allowed to begin with in the design of the Java language? It seemed like it could have been forbidden as a language restriction. Are there cases where doing this is necessary?

Uri
  • 88,451
  • 51
  • 221
  • 321
  • 1
    Makes compiling more difficult. [Just don't do it.](http://stackoverflow.com/questions/15327417/is-it-ok-to-call-abstract-method-from-constructor-in-java) – Sotirios Delimanolis Aug 10 '16 at 17:46
  • How does it make compiling more difficult? If the language had a restriction like "constructor can only call private or final instance methods" then that seems like it should be easy to validate at compile time. I'm asking this question because I'm looking at a lot of legacy code that does this extensively so I'm wondering why this was possible to begin with. – Uri Aug 10 '16 at 17:48
  • it's bad practice for the same reason as leaking `this` – obataku Aug 10 '16 at 17:53
  • For the sake of this question, besides just quoting a source, it would be good to include the actual reason why (you think) it is bad. Rather than just saying it is considered bad practice. – Jorn Vernee Aug 10 '16 at 17:59

1 Answers1

1

The Java language allows it because there is (was) no clear, uncontroversial reason to forbid it, specially if you consider that today's Java best practices were not necessarily known at the time the language was originally designed.

Note that a constructor calling an abstract or non-final method does work, because a subclass could override said method, and because the constructor may be executing on a newly-created instance of a subclass (due to constructor execution order from subclass to super class).

As far as I can tell, there is no case where doing it is necessary. But surely some third-party libraries out there do it, even if it is known to be a bad practice.

Rogério
  • 16,171
  • 2
  • 50
  • 63
  • "the constructor may be executing on a newly-created instance of a subclass (due to constructor execution order from subclass to super class)"--this is precisely the reason it's discouraged: you are calling instance methods on an object before it's been completely initialized – obataku Aug 10 '16 at 17:59
  • Back in the day when I first learned C++ (prior to Java being introduced), the argument about a predefined construction order (parent->child) was that it avoided the complexities of a parent constructor invoking virtual methods on the child since the child state is not valid yet. So it seems to me that there was at least some awareness of this issue in the original design. – Uri Aug 10 '16 at 18:36