Should we always have a zero-argument constructor in a Class? - java

Should every Java class have a zero-argument constructor?

No
If it makes no sense to create an instance of the class without supplying any information to the constructor then you need not have a zero-argument constructor.
A good example is java.awt.Color class, whose all ctors are argumented.

No, it doesn't make sense to always create zero argument constructors, the following scenarios are examples where it makes sense to provide at least a-some-argument-constructor
Required dependencies that the class itself cannot create.
There are no senseful defaults for the properties.
Cases where you want to have/need a zero-argument constructor:
You want to comply to the JavaBeans specification (makes sense for simple data objects).
All fields can be initialized using senseful defaults.
You want to use a framework that needs it.
One of the mis-arguments for having a zero-argument constructor in my opinion is a long list of arguments. For that there are better solutions than accepting to initialize an object that isn't in a safe state after creation:
Using the Builder pattern.
Provide specialized container objects to configure an instance via the constructor.
Provide multiple constructors where the base arguments of each one are the required parameters that cannot have defaults assigned.

As Andy Thomas-Cramer has already noted, it is even impossible:
class NeedsToBeImmutable {
// For a class to be immutable, its reachable state
// MUST be reached through a final field
private final String stuff;
//!!Compile error!!
public NeedsToBeImmutable(){}
public NeedsToBeImmutable(String stuff){
this.stuff = stuff;
}
//getters...
}

No. However there are exceptions. For instance, if you intend your class to contain just static util methods or a singleton class or a class with just constants then you should create a private constructor with no arguments to prevent it from being explicitly instantiated.

Related

Why did it become a convention to create a non-arg constructor in a javabean?

I know
A JavaBean is just a standard
All properties private (use getters/setters)
A public no-argument constructor
Implements Serializable.
Source
We all know it is not required to provide a non argument constructor in a class, because if we have not specified any constructor in our class java compiler will create a non argument constructor. If so why programmers wanted to create a non argument constructor in a javabean as a convention.
You are confusing requirements on the JavaBean class with the requirements on its source code. No part of the JavaBeans specification deals with how your source code must look like, it is strictly about the resulting class.
So yes, each JavaBeans class must provide a nullary constructor, and how you achieve that with source code (or even with a bytecode generator) is completely up to you.
It is considered good practice by some to always include the non-arg constructor in your code, because that prevents the scenario where a later maintenance introduces another constructor, thereby discarding the implicit non-arg one, thereby breaking any external code that relies on it.
You don't have to create it explicitly. There's no rule saying you have to do that. Even for a JavaBean, it's fine to leave the compiler to create one for you (as long as you're not providing another one, in which case you'd need an explicit no-arg constructor too).
But there does need to be one, explicit or implicit, because the ORM needs to be able to create instances.
You'd want to create a no argument in these cases:
1) You want to do some logic in the no argument constructor, so can't use the default.
2) You have other constructors that take arguments, in that case no default no-arg constructor will be provided for you.
point 2 implies that having an explicit no arg constructor to start with allows you to add future constructors with arguments without worrying about losing the implicit no-arg constructor.
Without one many API internals like ORMs or IOC containers can't instantiate the object in order to proceed with setting the bean properties from the data source or other bean dependencies.
Many do approximately this:
Class<?> clazz = Class.forName("com.foo.BeanClass");
Constructor<?> constructor = clazz.getConstructor();
Object bean = constructor.newInstance();

Java - what is a method with a apparently no signature

in other words, can someone explain to me the purpose of this:
Consumer(Producer p) {
producer = p;
}
in the context of:
class Consumer extends Thread {
Producer producer;
Consumer(Producer p) {
producer = p;
}
}
as I understand, it appears to be a method with no signature, or a constructor since it shares the class name, yet it doesn't show up in my IDE as such. Can someone explain what it is and what it does?
Any help would be hugely appreciated.
You are looking at a constructor of class Consumer. The only problem I can see is it is not given a access level (public, private, etc...), so it looks like it will default to package-protected, meaning only classes within the same package can see it.
Consumer(Producer p) { ... } is a constructor for the Consumer class.
You typically see constructors as public, e.g.:
public Consumer(Producer p) { ... }
However, when the public (or any access modifier, e.g. protected, or private) is not specified (for any method or member, including constructors), the constructor is only available to the package the class is declared in.
Have a look at Oracle's tutorial on access control.
Yes, that's a constructor. It may look like a "method with no signature" syntactically (more specifically, a constructor cannot have a return type, but may have access modifiers and of course parameters), but it's really quite different from a method in several ways.
The purpose of a constructor is to create instances (objects) of the class. With some relatively exotic exceptions (cloning and deserialization), every Java object is created by calling a constructor. Every class has at least one constructor, but if none is declared an the superclass has a constructor with no parameters, the compiler implicitly adds a parameterless constructor that does nothing except call the superclass constuctor. Similarly, the first thing any constructor does is call a superclass constructor. Again, this can be implicit if there is a parameterless constructor in the superclass.
As for why constructors don't show up in your ide: it's probably a configuration option. To say more, we'd have to know which IDE that is.
As already mentioned, that is a package protected constructor, i.e. it can only be called from methods of the class itself or other classes in the same package. I'm not sure what benefit that has over the more commonly used protected or private constructors, which prevent a class from being directly instantiated and are commonly used to implement the Singleton pattern.

Why do we need a default no argument constructor in Java?

Why do we need a default no argument constructor in many Java related APIs? Like as a general rule all java bean classes or entity classes (JPA etc) or JAX-WS implementation classes require a explicit no argument constructor.
If by default Java provides a no argument constructor then why most of these standards require a explicit constructor?
Java only provides a default no-argument constructor if no other constructors are defined. Thus, if you have other constructors you must explicitly define a no-arg constructor yourself.
These frameworks use the reflection API and look at method names to determine how to set properties. The arguments of a constructor can only be found by type, not by name, so there is no way for the framework to reliably match properties to constructor args. Therefore, they require a no-arg constructor to create the object, then can use the setter methods to initialise the data.
Some frameworks may support #ConstructorProperties as an alternative.
I believe frameworks that require public nullary constructors do so because they use reflection to instantiate types, e.g. through Class.newInstance().
As to why the default constructor may not work for this case, here's the relevant JLS section:
JLS 8.8.9 Default Constructor
If a class contains no constructor declarations, then a default constructor that takes no parameters is automatically provided:
if the class is declared public, then the default constructor is implicitly given the access modifier public;
if the class is declared protected, then the default constructor is implicitly given the access modifier protected;
if the class is declared private, then the default constructor is implicitly given the access modifier private;
otherwise, the default constructor has the default access implied by no access modifier.
So in a public class, the default constructor would have the right visibility, but otherwise an explicitly public one must be provided.
A constructor is needed to initialise any non-default values and can contain side effects which are needed.
If you have a programing style which encourages a minimal constructor for data transfer objects this would seem unneccasary, but the libraries have chosen not to assume any programming style for the constructors.
You can write a library which doesn't assume a default constructor, but you have to make assumptions about what the constructor would do and wouldn't do. i.e. I have written such libraries but was able to also mandate what a constructor was allowed to do so that not calling it directly was safe.
Java only supplies a no-arg constructor if no other constructor is applied. In a number of Java APIs (e.g. JPA, Serialisation and many others that build objects from an external representation) an instance of the object is required before the data values of the object can be set, as the definition of how the values are applied are defined through instance members of the object (e.g. readExternal(ObjectInput)). If a class only has a constructor that takes some arguments then it may not be possible for the library to construct an instance unless a separate no-arg constructor is defined.
It is worth noting that this is a design choice by the implementer of the particular library, it is possible to build an API/Framework that can externalise and recreate objects that don't have a no-arg constructor (defining a separate factory class is one approach). The pattern of requiring a no-arg constructor turned up first in Java Serialisation (I think) and has been adopted as the de-facto standard approach on other libraries (e.g. JPA). The weakness of this approach is that it prevents the use of immutable objects.
Two reasons:
1) to avoid NullPointerException if an instance data field of a reference data type is uninitialized. Providing an explicit constructor would give you the chance to initialize such data fields, if they have not been initialized when declared
2) for users who would like to use no-arg constructors; these are not automatically provided if other constructors exist
Many of these frameworks derive from the earlier ideas of "POJO" and especially JavaBeans. The smallest useful Java Object would, by convention, have a no-arg constructor and every member accessible through methods like get/setProperty1 and is/setProperty1 for booleans. If Classes follow that convention of the interface, tools and frameworks using reflection can work 'out of the box'.
Default No-Argument constructor provides default values to the object like 0 or null, hence it is mandatory in java coding.

Object construction from serialization - which is preferred?

Lets say you have a class SomeClass which has its own implementation of toString(), and also has the ability to parse a new instance of itself by reading that same string.
Which of these methods do you prefer, or find better to use?
You can either define it as another constructor:
public SomeClass(String serializedString);
or you can define it as a static method, which in turn creates a new instance (by one of the other constructors, does some with it, and returns the new instance:
public static SomeClass toObject(String serializedString);
Does it even matter? (my hunch is there is no case this matters, but I am trying to make sure)
My own preference is to keep the parsing logic out of the constructor. That way it can call the appropriate constructors (possibly private) as necessary. It doesn't have to depend on default object construction and so on. So I would go with the toSomeClass() method.
Also, it is not immediately clear that SomeClass(String) will parse an object based on the serialization string. There may be many other meanings to a constructor which takes a String. The toSomeClass() static method makes this clear.
I agree with Avi's recommendation. I'd like to add two more advantages:
A static factory method allows you to return null, which a constructor can't.
A static factory method allows you to return a subclass of its defined return type, which can help provide forward compatibility.
One exception: if you're writing a simple value type and using the immutable pattern, I see no reason to use a static factory method.
The static method has the advantage that you can then use the string-reading constructor for something else. Also in general it's better to use static factories than constructors in any nontrivial classes. It gives you more flexibility.
A Java convention for such static methods is:
public class Foo {
// ...
public Foo parseFoo (String s) {...}
// ...
}
as in the standard parseInt(...), parseLong(...), parseDouble(...), etc. Unfortunately, Sun also gave us a different convention with the wrapper classes, as in Boolean.valueOf(...). However, I'd pick one of those conventions and follow it consistently.
To keep some specific logic (like parsing from string) out of constructor is good design policy.
Constructor job is mainly object creation. Initialization and creation of it's fields.
Serialization logic need to be separated from creation. Firstly you may wan't to create separate static method, secondly in evolution of your class you may want to implement some kind of Serializable interface and delegate reading/writing job to another class.
Another advantage to a static constructor is that you can give it a meaningful name. In this case, I would suggest parse:
SomeClass inst = SomeClass.parse("wibble");

Why might one also use a blank constructor?

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?
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.
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
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.
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.
The default constructor is'nt a good pratice for the functional view.
The default constructor is used if the object have a global visibility into a method: for example, you want log the actual state of a object in a try/catch
you can code
MyObejct myObject=null
try{...
}catch(Exception e){
log.error(myObject);//maybe print null. information?
}
or do you prefer
MyObejct myObject=new Object();
try{...
}catch(Exception e){
log.error(myObject);//sure print myobject.toString, never null. More information
}
?
Anotherway the create a EMPTY object have'nt a lot of logic, but instatiate a NULL object is harmuful in my opinion.
You can read this post
That is NOT a copy constructor. Basically you want empty constructors when working with some framework. Shall there always be an empty constructor, of course, public or private, but at least it allows you to keep control of how the class is being (or not) instantiated.
I usually write one constructor that fully initializes the object; if there are others, they all call this(...) with appropriate defaults.
An object should be 100% initialized and ready for use when it's created.
Some frameworks, for example Hibernate, demand a no-arg constructor. The way they clash with best practices makes me uneasy sometimes.
Having a default and empty (blank) constructor prevents you from having any final fields. This leads to a lot of mutability where there it is often not needed.
The builder pattern allows you to mix these two styles and allow more flexible initialization while still having immutability by hiding a many-arg constructor behind the factory.
For some POJO classes or simple class, default constructor is useful when you sometimes want to do unit testing on the class using them. You don't need to mock them, you can new an object with default constructor and test the value set and get from them or pass them as an argument.
You want to create a blank constructor for the classes that extended this
class and since it has been extended the class... the child now has super which references the class above it it's parent. In the event the child did not specify super(stuff)... the stuff inside to reference the other constructors to use it will now attempt to reference the empty constructor.
I'm not sure what the error will be I am coding my first parent object relationship now and was looking up things here ha cheers.
I guess I should add the moment you make a constructor that isn't the empty one you lose the default empty one so now super() which is default in the extended class won't have something to point to. Of course if you created the extended classes to take care of super by specifying on which gets rid of the default super() then you sidestep this but what if someone wants to use your class and extend from it and didn't realize there isn't an empty set when you could have
just created one.
This is my first post but wanted to take a crack from how I understand it.

Categories