Campbell Ritchie wrote:
Tim Holloway wrote:. . . Besides, you can't have a decent POJO without a no-element constructor.
Please explain. I agree with Carey.
As it happens, I got a very real-world reinforcement of why no-argument constructors are desirable just this past week. More in a minute.
First (and somewhat related) has to do with Inversion of Control (IoC) frameworks.
In a typical IoC system, you often have an inventory of instantiable classes and a factory/warehouse to dispense instances. So generally, the factory is going to have to construct instances.
If all your classes have no-element constructors, you have a virtually zero-knowledge system. Need an instance? Get the classname and do a "newInstance()" on it. Or actually, use Constructor, since newInstance() is now deprecated.
If your constructors have arguments, you are going to need more knowledge. You are going to need to know the number and types of the constructor arguments
and sources for the values you'll feed it.
That's one of the selling points of the Spring Framework, incidentally. That you can setup bean definition files and manually wire source values to constructors. On the other hand, note the
word "manually". If your classes are all no-element constructors, you can scan directories and/or annotations to build up the bean list. On the other hand, if you need constructor arguments, you're going to have to handle that the hard way.
Note that this is different to injection. Injection mechanisms add data to an instance AFTER the constructor has terminated - although before normal application code gets a crack at it. So injection is a favoured system for frameworks like CDI and the JavaServer Faces bean management system (which has been supplanted by CDI, but is still around).
JSF doesn't, in fact, have any support for constructor arguments at all. If a JSF backing bean cannot be constructed by a simple "newInstance()" it's not a usable backing bean.
So that's reason #1. It's not really a "POJO" if it doesn't have a no-element constructor and in fact, I think that the technical definition of POJO does in fact REQUIRE either a no-element constructor or implicit construction (which is effectively the same thing).
There's another situation where no-element constructors are important. Object Relational Management (ORM) systems. Again, we need to be able to construct an object without knowing where/what construction values are. When an ORM goes to fetch a record from a database, having a blank record that it can simply pour all the column field values in is much more preferable to having to take some of them and feed them to a constructor and some populated directly. I could expand on this, but I think you get the point.
And then there's my own personal experience. Very recently I ran into a situation where a LOT of objects needed to be constructed. Even better, it was an interface-based system where an entirely different situation (and class) was required for the
testing environment
versus the production environment. Since the objects in question did NOT have no-element constructors, I ended up having to introspect each and every class definition for the objects in question so that I could do a "newInstance-with-arguments". You saw some of the echoes of my pain in the form of pleas for help on the Ranch.
Mind you, what I did was extremely crude. Thanks to things like subclassing and interfaces, I couldn't simply throw a list of values at the class definition and get what I wanted. I had to scan the entire list of available constructors and match the values supplied to the constructor argument lists to see which constructor to invoke. And I was definitely NOT in the mode to apply full disambiguation rules as laid down in the JLS. So it was crude and brutal and wouldn't have worked if the environment had been much more complex.
So there you have 3 arguments in favour of no-argument default constructors.