Why it is not a good idea to call Set method from constructor?

前端 未结 6 1367
梦毁少年i
梦毁少年i 2020-12-18 09:57

Is it true only in Inheritance or most of the cases ?

public class MyClass {
   public int id;

     public MyClass() {
         // Some stuff 
         setI         


        
相关标签:
6条回答
  • 2020-12-18 10:31

    If it was just setter method you want, then initialize your variable from the constructor itself.

    public class MyClass {
        int id; 
        public MyClass() { 
            id=5;   
        }
    }
    

    Otherwise, you can call private/final methods to comply OOP theory.

    Remember, an object initialization will only be completed after executing the last statement in a constructor or when exiting the constructor.

    [update]

    A similar, more interesting discussion is happening here

    Java - Subclass calls supers constructor which calls subclass method instead of its own

    0 讨论(0)
  • 2020-12-18 10:35

    Since in Java, all functions are virtual by default, unsealed method calls in the ctor are risky for reasons explained in this thread.

    That's why you might want to make either SetId or MyClass final or private.

    0 讨论(0)
  • 2020-12-18 10:37

    You should not call an overridable method from a constructor.

    If you call a method that can be overridden by a subclass in a costructor, than the subclass might access variables of the superclass that have not been initialized yet.

    For example the following code looks good so far

    class MyClass {
        public int id;
        protected String someStr;
    
        public MyClass() {
            SetId(5);
            someStr = "test";
        }
    
        public void SetId(int Id) {
            id = Id;
        }
    }
    

    If you now subclass MyClass and override the SetId method you might access the superclass's someStr variable which has not been initialized yet and thus will cause a NullPointerException in this case.

    class MySubClass extends MyClass {
    
        public void SetId(int Id) {
           id = Id;
           someStr.toString(); // will cause NullPointerException
        }
    }
    

    The cause of the NPE might be hard to see if there is a bigger inheritence hierarchy.

    0 讨论(0)
  • 2020-12-18 10:40

    It is very true.

    Because setters are always public methods. And if you class is not final then there is issue of alien method call. Which is not thread safe i.e. it is known as escaping of this reference. So from a constructor if you are calling a method it should be final or private. Else safe initialization of object will not happen which causes many bugs in real systems.

    Apart from the above we should never call public method from the constructor because if the class is intended for inheritance than 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.

    source.

    0 讨论(0)
  • 2020-12-18 10:46

    It is probably not a good idea. If you don't make that class final and don't make the setName( ... ) method private or final someone else is able to extend your class and overrid the setName( ... ) method. Your constructor (in your base class) will call that method in the extending class instead of your implementation. Nobody knows what that method can do. As a rule of thumb: a constructor shouldn't call methods that can be overriden

    0 讨论(0)
  • 2020-12-18 10:53

    The constructor constructs the object and you should only call things that you know work in the 'not fully constructed state'. In your example the SetId does nothing other that set a value so it's fine. However if SetId used other state/infothat wasn't ready yet then you could run into an issue.

    It's not a commandment - rather it's a 'be wary of what you do'

    0 讨论(0)
提交回复
热议问题