Why might one also use a blank constructor?

18,826

Solution 1

I am not sure that the code you were reading was high quality (I've reviewed some bioinformatics code in the past and it is unfortunately often not written by professional developers). For example, that third constructor is not a copy constructor and generally there are problems in this code, so I wouldn't "read too much into it".

The first constructor is a default constructor. It only initializes the bare minimum and lets users set the rest with getters and setters. Other constructors are often "convenience constructors" that help create objects with less calls. However, this can often lead to inconsistencies between constructors. In fact, there is recent research that shows that a default constructor with subsequent calls to setters is preferable.

There are also certain cases where a default constructor is critical. For example, certain frameworks like digester (used to create objects directly from XML) use default constructors. JavaBeans in general use default constructors, etc.

Also, some classes inherit from other classes. you may see a default constructor when the initialization of the parent object is "good enough".

In this specific case, if that constructor was not defined, one would have to know all the details in advance. That is not always preferable.

And finally, some IDEs automatically generate a default constructor, it is possible that whoever wrote the class was afraid to eliminate it.

Solution 2

Is the object Serializable?

To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.

During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream

Solution 3

Yes, I agree the "blank" constructor should not always exist (in my experience beginners often make this mistake), although there are cases when blank constructor would suffice. However if the blank constructor violates the invariant that all the members are properly instantiated after construction, blank constructor should not be used. If the constructor is complicated, it is better to divide the construction into several protected/private methods. Then use a static method or another Factory class to call the protected methods for construction, as needed.

What I wrote above is the ideal scenario. However, frameworks like spring remove the constructor logic out of the code and into some xml configuration files. You may have getter and setter functions, but probably may be avoided from the interface, as described here.

Solution 4

Default constructor is NOT mandatory.

If no constructors defined in the class then default (empty) constructor will be created automatically. If you've provided any parametrized constructor(s) then default constructor will not be created automatically and it's better to create it by yourself. Frameworks that use dependency injection and dynamic proxy creation at runtime usually require default constructor. So, it depends on use cases of class that you write.

Share:
18,826
user2918201
Author by

user2918201

In August of 2008 I became curious about Ruby and took up programming as a hobby. Since then I have become curious about a lot of other things, and my aspirations have quickly expanded. I very much enjoy programming, and the open source phenomenon strikes me as a window into a sustainable future. I hope that in a few years I will be able to join the scene and contribute to that future. My dreams and ambitions have been multiplied! In 2009 I decided that I would, at the age of 26, return to university and get a degree in computer science. To that end I began studying math, something I had never done before. In summer of 2010 I enrolled in a college and began taking first year computer science courses. By this time I was completely roped in by the beauty of programming. At the time I hoped to be able to transfer to a university by summer of 2011 and receive my first degree in 2014. Rather than transferring to a university, though, I took on an internship. A friend I had met through Elysian coffee, my part time job, offered to take me on as his intern in the spring of 2011 while I was taking courses. This internship turned full time during the summer, and I worked on a number of Rails and Mac projects, mostly in ruby. My love of Ruby increased tenfold, as did my understanding of the programmer's ecosystem. University transfer was pushed back to the summer of 2012, but my goal was still to graduate in 2014. Having worked with a freelance programmer for some time, I decided that after graduating, but before entering the workforce, I would dedicate some time to personal projects. At about the time these thoughts occurred to me I became aware that Canada had established a working holiday visa treaty with Taiwan. I resolved to take advantage of this unique opportunity, and to spend the end of 2014 (the year I would turn 30) and the beginning of 2015 in Taiwan as a master-less programmer. Ultimately I would like to use computer science to help "save the world". Once I have learned enough, I hope to be able to dedicate myself to whatever desperately needs doing. Whether that be related to energy, or poverty, or space travel, I want to be there with those people computing what they need computed.

Updated on July 29, 2022

Comments

  • user2918201
    user2918201 almost 2 years

    I was reading some Java recently and came across something (an idiom?) new to me: in the program, classes with multiple constructors would also always include a blank constructor. For example:

    public class Genotype {
      private boolean bits[];
      private int rating;
      private int length;
      private Random random;
    
      public Genotype() {              //  <= THIS is the bandit, this one right here
        random = new Random();
      }
    
      /* creates a Random genetoype */
      public Genotype(int length, Random r) {
        random = r;
        this.length = length;
        bits = new boolean[length];
    
        for(int i=0;i<length;i++) {
            bits[i] =random.nextBoolean();
        }
      }
    
      /* copy constructor */
      public Genotype(Genotype g,Random r) {
        random = r;
        bits = new boolean[g.length];
        rating = g.rating;
        length = g.length;
    
        for(int i=0;i<length;i++) {
            bits[i] = g.bits[i];
        }
    
      }
    }
    

    The first constructor doesn't seem to be a "real" constructor, it seems as though in every case one of the other constructors will be used. So why is that constructor defined at all?