Instantiating object in a constructor

前端 未结 6 883
醉梦人生
醉梦人生 2020-12-28 23:43

It seems that the result of the following code is the same, so when should I use each?

public class Person {
   public Person() {
       this.family = new Fa         


        
相关标签:
6条回答
  • 2020-12-29 00:20

    The second style is terrible if you plan to extend the class (see Daff's answer).

    For instance variables, I believe that is is clearer to the maintenance programmer - who is typically a junior programmer - to perform all instance level initialization in the constructor. I recommend a variation of your option 1.

    public class Person
    {
      private Family family;
    
      public Person()
      {
        family = new Family();
      }
    }
    

    I prefer to avoid this when it is not necessary, since it adds nothing.

    0 讨论(0)
  • 2020-12-29 00:21

    I would recommend using the first when it comes to subclassing. Consider this:

    public class Child extends Person {
       public Child() {
            // super();
            // or
            this.family = new PatchWorkFamily();
       }
    }
    

    With the second way of initializing you will always initialize a new Family and then overwrite it if needed. That might not be what you want - and can be bad for performance if these object do a lot of work when being instantiated.

    0 讨论(0)
  • 2020-12-29 00:24

    For class variables [static variable] you cannot use the first, since you want the initializtion to happen only once, and not with every time you invoke your constructor.

    For instance variables, the second is just a syntatic sugar of the first.
    Sometimes you might have to use the second - for argument constructor, which are themselves - passed to your constructor.

    0 讨论(0)
  • 2020-12-29 00:28

    The first method gives you custom control over how to initialize the class object that you're dealing with per constructor, whereas the second option will initialize the Family object the same way for all constructors.

    The first method is preferable, because it allows you to take a Family object into your constructor allowing you to do things like dependency injection, which is generally good programming practice (and allows for easier testing).

    Aside from that, both of them are member variables (not static as someone else said, you have to use the static keyword for that). Each instance of this class will contain an instance of a Family object this way.

    I would recommend something like this

    public class Person {
        public Person(Family family) {
           this.family = family;
      }
      Family family;
    }
    

    Edit: To address the comment that was made about my post (which was accurate, somewhat), there is a difference in which the order of the objects are initialized. However, the comment stated that the order of operation is:
    initialization of instances variables -> instance initializer -> constructor

    From testing this out, it seems that it depends on which occur first in the code, initialization of instance variables or instance initializers, and then the constructor is called after both of them. Consider the example where the constructor of the Family object just prints out the string given to it:

    public class Person {
        {
            Family familyB = new Family("b");
        }
        Family familyA = new Family("a");
    
        Family familyC;
        public Person() { 
            this.familyC = new Family("c");
        }
    }
    

    results in this output when constructing a person object:
    Family: b
    Family: a
    Family: c

    but this code:

    public class Person {
        Family familyA = new Family("a");
        {
            Family familyB = new Family("b");
        }
    
        Family familyC;
        public Person() { 
            this.familyC = new Family("c");
        }
    }
    

    results in this output when constructing a person object:
    Family: a
    Family: b
    Family: c

    0 讨论(0)
  • 2020-12-29 00:31

    The latter will guarantee that every Person will always have a Family (awww, isn't that nice). But in the former, other constructors could be added by another developer which leave Family uninitialized. That tends to suggest the latter, shorter version is preferable. But that is not really true, because it might be a valid condition to model a Person as not having a family, in which case initialization via constructor is superior because you can pass null.

    The 3rd alternative is the (longer, sigh) basic POJO style with provided setter, in which Family is not initialized until a setter is explicitly called. The nicer thing about using this is that you don't have to provide a null value to a constructor if you are modeling an Orphan.

    It all depends on how you want to constrain construction of Person.

    0 讨论(0)
  • 2020-12-29 00:32

    I like the second style better. If you have more than one constructor you don't have to repeat the initializations and you wont forget them. Also, it makes it clear how the variable is initialized. Typically, when reading a program and coming across a variable, you'll first go to its declaration. With the second style, you see the default value right away. With the first, you need to look at the constructor.

    Neither is computationally superior.

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