Why a constructor should not throw an exception?

Why a constructor should not throw an exception?

Just imagine if somebody asks you to do some task and when you have done 80% of it they come and ask to stop. Because you have not met preconditions for it. How will you feel about it? Something similar happens when you throw an exception from a constructor.

What are constructors? (If you already understand this, let’s revisit or just skip to next para)

A constructor is a special method that is responsible for initialization of the variable of a class and returns a newly created instance of that class. We do not define a return type of constructs as they always return an object of the class they are defined in. Their names will always be same as class name.

 

class Car {

	private int cylinder;

	public Car(int cylinder) {
		super();
		this.cylinder = cylinder;
	}

}

Next thing that we need to understand for this is constructor chaining.

Constructor Chaining

If you have never heard this thing before then let me introduce to constructor chaining.

In Java, A class can extend exactly one class and if it does not extend any class then the compiler will make some change and your class will extend java.lang.Object class.

In your class you define some constructors and these constructors will either have their first statement as a this(<Parameter if any>) or a super(<Parameter if any>). Most of the time you don’t give these statements. In that case, the compiler makes some changes and add super() to your constructor. Now you wonder why? Well, the answer is, when your object will be created then there are some tasks that need to be performed before your object starts initializing and these steps are defined in Object class. If you already extend some class then your parent class may need to do some tasks or initialize it’s variable to get going with your child.

Here we can say that “A child cannot be born before its father”. Your parent

After all, that’s why we have inheritance so that you can reuse the functionality of your parent and for that parent needs to be initialized before use.

This whole concept of calling one constructor from another is called constructor chaining.

class Car {

	private int cylinder;

	public Car(int cylinder) {
		super();
		this.cylinder = cylinder;
	}

}

class Audi extends Car {

	public Audi(int cylinder) {
		// calling super class constructor as it needs to initialize cylinder of parent
		super(cylinder);
	}

	public Audi() {
		// calling above constructor 
		this(4); // here we can also have a call to super, but not both
	}

}

Now just think if your constructor is throwing an exception at the third link or first maybe while reading from some CSV what will happen?

Your construction will break but before that, contractors of all its parents (including Object class) will be called and all those efforts will be a waste of time and memory.

class Car {

	private int cylinder;

	public Car(int cylinder) {
		super();
		this.cylinder = cylinder;
	}

}

class Audi extends Car {

	public Audi(int cylinder) {
		// calling super class constructor as it needs to initialize cylinder of parent
		super(cylinder);
	}

	public Audi() {
		// calling above constructor 
		this(4); // here we can also have a call to super, but not both
		
		// here I got some weird situation and want to throw an exception
		throw new IllegalArgumentException("You input is not correct");
		// OOPS! we have already done bunch of tasks before throwing from here.
		// Also don't forgot the memory allocations and you may have a long hierarchy of classes
	}

}

One possible solution can be using a method that does the tasks that may throw an exception and then call the constructor to you avoid unnecessary steps. Yes, that is using a factory design pattern.

Now you know why it is always disgraced to throw an exception from a constructor.

Leave a Reply

Your email address will not be published. Required fields are marked *