Class OverridableMethodInConstructorCheck

  • All Implemented Interfaces:
    com.puppycrawl.tools.checkstyle.api.Configurable, com.puppycrawl.tools.checkstyle.api.Contextualizable

    public class OverridableMethodInConstructorCheck
    extends com.puppycrawl.tools.checkstyle.api.AbstractCheck
    Detects overridable methods in constructors.

    This check prevents any calls to overridable methods that are take place in:

    1. Any constructor body (verification is always done by default and not configurable).
    2. Any method which works same as a constructor: clone() method from Cloneable interface and readObject() method from Serializable interface (you can individually switch on/off these methods verification by changing CheckCloneMethod and CheckReadObjectMethod properties).
    Rationale:
    1. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will be invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.
    2. If you do decide to implement Cloneable or Serializable in a class designed for inheritance, you should be aware that because the clone and readObject methods behave a lot like constructors, a similar restriction applies: neither clone nor readObject may invoke an overridable method, directly or indirectly.
    [Joshua Bloch - Effective Java 2nd Edition, Chapter 4, Item 17]
    Here's an example to illustrate:
     public class Example {
        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; }
                void overrideMe() {
                    System.out.println(x);
                }
            }
            new Child(42); // prints "0"
        }
     }

    Here, when Base constructor calls overrideMe, Child has not finished initializing the final int x, and the method gets the wrong value. This will almost certainly lead to bugs and errors.

    Notes:

    This check doesn`t handle the situation when there is a call to an overloaded method(s).

    Here`s an example:

     public class Test {
    
       public static void main(String[] args) {
    
           class Base {
               Base() {
                   System.out.println("Base C-tor ");
                   overrideMe("Foo!"); // no warnings here, because the method
                                       // named "overrideMe" is overloaded.
               }
               void overrideMe() { }
               void overrideMe(String str) {
                   System.out.println("Base overrideMe(String str) ");
               }
           }
    
           class Child extends Base {
               final int x;
               Child(int x) {
                   this.x = x;
               }
               void overrideMe(String str) {
                   System.out.println("Child`s overrideMe(): " + x);
               }
           }
         new Child(999);
       }
     } 


    Some specific method call types that aren`t supported by check:

    • BaseClass.InnerClass.this.methodName();
    • InnerClass.this.methodName();
    • and so on, using a similar hierarchy

    Since:
    1.8.0
    Author:
    Daniil Yaroslavtsev, Ilja Dubinin
    • Nested Class Summary

      • Nested classes/interfaces inherited from class com.puppycrawl.tools.checkstyle.api.AutomaticBean

        com.puppycrawl.tools.checkstyle.api.AutomaticBean.OutputStreamOptions
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static String MSG_KEY
      A key is pointing to the warning message text in "messages.properties" file.
      static String MSG_KEY_LEADS
      A key is pointing to the warning message text in "messages.properties" file.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void beginTree​(com.puppycrawl.tools.checkstyle.api.DetailAST rootAST)  
      int[] getAcceptableTokens()  
      int[] getDefaultTokens()  
      int[] getRequiredTokens()  
      void setCheckCloneMethod​(boolean value)
      Enable|Disable searching of calls to overridable methods from body of any clone() method is implemented from Cloneable interface.
      void setCheckReadObjectMethod​(boolean value)
      Enable|Disable searching of calls to overridable methods from body of any readObject() method is implemented from Serializable interface.
      void setMatchMethodsByArgCount​(boolean value)
      Enable|Disable matching methods by arguments count.
      void visitToken​(com.puppycrawl.tools.checkstyle.api.DetailAST detailAST)  
      • Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractCheck

        clearViolations, destroy, finishTree, getFileContents, getFilePath, getLine, getLineCodePoints, getLines, getTabWidth, getTokenNames, getViolations, init, isCommentNodesRequired, leaveToken, log, log, log, setFileContents, setTabWidth, setTokens
      • Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter

        finishLocalSetup, getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, setId, setSeverity
      • Methods inherited from class com.puppycrawl.tools.checkstyle.api.AutomaticBean

        configure, contextualize, getConfiguration, setupChild
    • Field Detail

      • MSG_KEY

        public static final String MSG_KEY
        A key is pointing to the warning message text in "messages.properties" file.
        See Also:
        Constant Field Values
      • MSG_KEY_LEADS

        public static final String MSG_KEY_LEADS
        A key is pointing to the warning message text in "messages.properties" file.
        See Also:
        Constant Field Values
    • Constructor Detail

      • OverridableMethodInConstructorCheck

        public OverridableMethodInConstructorCheck()
    • Method Detail

      • setCheckCloneMethod

        public void setCheckCloneMethod​(boolean value)
        Enable|Disable searching of calls to overridable methods from body of any clone() method is implemented from Cloneable interface.
        Parameters:
        value - The state of a boolean check box that enables the searching of calls to overridable methods from body of any clone() method is implemented from Cloneable interface.
      • setMatchMethodsByArgCount

        public void setMatchMethodsByArgCount​(boolean value)
        Enable|Disable matching methods by arguments count.
        Parameters:
        value - The state of a boolean check box that enables the matching of methods by arguments count.
      • setCheckReadObjectMethod

        public void setCheckReadObjectMethod​(boolean value)
        Enable|Disable searching of calls to overridable methods from body of any readObject() method is implemented from Serializable interface.
        Parameters:
        value - The state of a boolean check box that enables the searching of calls to overridable methods from body of any readObject() method is implemented from Serializable interface.
      • getDefaultTokens

        public int[] getDefaultTokens()
        Specified by:
        getDefaultTokens in class com.puppycrawl.tools.checkstyle.api.AbstractCheck
      • getAcceptableTokens

        public int[] getAcceptableTokens()
        Specified by:
        getAcceptableTokens in class com.puppycrawl.tools.checkstyle.api.AbstractCheck
      • getRequiredTokens

        public int[] getRequiredTokens()
        Specified by:
        getRequiredTokens in class com.puppycrawl.tools.checkstyle.api.AbstractCheck
      • beginTree

        public void beginTree​(com.puppycrawl.tools.checkstyle.api.DetailAST rootAST)
        Overrides:
        beginTree in class com.puppycrawl.tools.checkstyle.api.AbstractCheck
      • visitToken

        public void visitToken​(com.puppycrawl.tools.checkstyle.api.DetailAST detailAST)
        Overrides:
        visitToken in class com.puppycrawl.tools.checkstyle.api.AbstractCheck