java - What's wrong with overridable method calls in constructors? -


i have wicket page class sets page title depending on result of abstract method.

public abstract class basicpage extends webpage {      public basicpage() {         add(new label("title", gettitle()));     }      protected abstract string gettitle();  } 

netbeans warns me message "overridable method call in constructor", should wrong it? alternative can imagine pass results of otherwise abstract methods super constructor in subclasses. hard read many parameters.

on invoking overridable method constructors

simply put, wrong because unnecessarily opens possibilities many bugs. when @override invoked, state of object may inconsistent and/or incomplete.

a quote effective java 2nd edition, item 17: design , document inheritance, or else prohibit it:

there few more restrictions class must obey allow inheritance. constructors must not invoke overridable methods, directly or indirectly. if violate rule, program failure result. superclass constructor runs before subclass constructor, overriding method in subclass invoked before subclass constructor has run. if overriding method depends on initialization performed subclass constructor, method not behave expected.

here's example illustrate:

public class constructorcallsoverride {     public static void main(string[] args) {         abstract class base {             base() { overrideme(); }             abstract void overrideme();          }         class child extends base {             final int x;             child(int x) { this.x = x; }             @override void overrideme() {                 system.out.println(x);             }         }         new child(42); // prints "0"     } } 

here, when base constructor calls overrideme, child has not finished initializing final int x, , method gets wrong value. lead bugs , errors.

related questions

see also


on object construction many parameters

constructors many parameters can lead poor readability, , better alternatives exist.

here's quote effective java 2nd edition, item 2: consider builder pattern when faced many constructor parameters:

traditionally, programmers have used telescoping constructor pattern, in provide constructor required parameters, single optional parameters, third 2 optional parameters, , on...

the telescoping constructor pattern this:

public class telescope {     final string name;     final int levels;     final boolean isadjustable;      public telescope(string name) {         this(name, 5);     }     public telescope(string name, int levels) {         this(name, levels, false);     }     public telescope(string name, int levels, boolean isadjustable) {                this.name = name;         this.levels = levels;         this.isadjustable = isadjustable;     } } 

and can of following:

new telescope("x/1999"); new telescope("x/1999", 13); new telescope("x/1999", 13, true); 

you can't, however, set name , isadjustable, , leaving levels @ default. can provide more constructor overloads, number explode number of parameters grow, , may have multiple boolean , int arguments, make mess out of things.

as can see, isn't pleasant pattern write, , less pleasant use (what "true" mean here? what's 13?).

bloch recommends using builder pattern, allow write instead:

telescope telly = new telescope.builder("x/1999").setadjustable(true).build(); 

note parameters named, , can set them in order want, , can skip ones want keep @ default values. better telescoping constructors, when there's huge number of parameters belong many of same types.

see also

related questions


Comments

Popular posts from this blog

php - How to display all orders for a single product showing the most recent first? Woocommerce -

asp.net - How to correctly use QUERY_STRING in ISAPI rewrite? -

angularjs - How restrict admin panel using in backend laravel and admin panel on angular? -