What kinds of constructor does Java support, and how do the default, parameterised and copy kinds differ in what they guarantee?
Three shapes cover almost everything. A default constructor takes no arguments and is the one the compiler generates for you when the class declares no constructor at all. A parameterised constructor accepts the values an object needs, usually as constructor arguments. A copy constructor accepts an instance of the same class and produces a new instance from it.
public class Main {
public static void main(String[] args) {
Product plain = new Product();
Product priced = new Product("Notebook", 4.5);
Product copy = new Product(priced);
System.out.println(plain);
System.out.println(priced);
System.out.println(copy);
}
}
class Product {
private String name;
private double price;
Product() { this.name = "unnamed"; this.price = 0.0; }
Product(String name, double price) { this.name = name; this.price = price; }
Product(Product other) { this.name = other.name; this.price = other.price; }
public String toString() { return name + "@" + price; }
}The output shows the three in use. The first product is unnamed at price zero, the second carries the values it was given, and the third was built from the second and reproduces its name and price. Notice what the copy constructor does not do here: it copies the two primitive fields by value, so the new product is genuinely independent as far as those fields go.
The important caveat is that a copy constructor only copies what you write in it. Once a class holds a mutable reference such as a list, copying the reference is not enough, because both objects would then share one list. The copy constructor has to make a fresh copy of that structure, which is exactly what the deep copy question is about.
A second point worth making: the compiler-generated default constructor leaves fields at their zero values, which is often not what you want. If a class should never exist in a half-initialised state, declaring even a trivial constructor and assigning sensible defaults is better than relying on the implicit one.