[java] Is it good practice to make the constructor throw an exception?

Is it a good practice to make the constructor throw an exception? For example I have a class Person and I have age as its only attribute. Now I provide the class as

class Person{
  int age;
  Person(int age) throws Exception{
   if (age<0)
       throw new Exception("invalid age");
   this.age = age;
  }

  public void setAge(int age) throws Exception{
  if (age<0)
       throw new Exception("invalid age");
   this.age = age;
  }
}

This question is related to java exception constructor

The answer is


You do not need to throw a checked exception. This is a bug within the control of the program, so you want to throw an unchecked exception. Use one of the unchecked exceptions already provided by the Java language, such as IllegalArgumentException, IllegalStateException or NullPointerException.

You may also want to get rid of the setter. You've already provided a way to initiate age through the constructor. Does it need to be updated once instantiated? If not, skip the setter. A good rule, do not make things more public than necessary. Start with private or default, and secure your data with final. Now everyone knows that Person has been constructed properly, and is immutable. It can be used with confidence.

Most likely this is what you really need:

class Person { 

  private final int age;   

  Person(int age) {    

    if (age < 0) 
       throw new IllegalArgumentException("age less than zero: " + age); 

    this.age = age;   
  }

  // setter removed

I've always considered throwing checked exceptions in the constructor to be bad practice, or at least something that should be avoided.

The reason for this is that you cannot do this :

private SomeObject foo = new SomeObject();

Instead you must do this :

private SomeObject foo;
public MyObject() {
    try {
        foo = new SomeObject()
    } Catch(PointlessCheckedException e) {
       throw new RuntimeException("ahhg",e);
    }
}

At the point when I'm constructing SomeObject I know what it's parameters are so why should I be expected to wrap it in a try catch? Ahh you say but if I'm constructing an object from dynamic parameters I don't know if they're valid or not. Well, you could... validate the parameters before passing them to the constructor. That would be good practice. And if all you're concerned about is whether the parameters are valid then you can use IllegalArgumentException.

So instead of throwing checked exceptions just do

public SomeObject(final String param) {
    if (param==null) throw new NullPointerException("please stop");
    if (param.length()==0) throw new IllegalArgumentException("no really, please stop");
}

Of course there are cases where it might just be reasonable to throw a checked exception

public SomeObject() {
    if (todayIsWednesday) throw new YouKnowYouCannotDoThisOnAWednesday();
}

But how often is that likely?


Throwing exceptions in a constructor is not bad practice. In fact, it is the only reasonable way for a constructor to indicate that there is a problem; e.g. that the parameters are invalid.

I also think that throwing checked exceptions can be OK1, assuming that the checked exception is 1) declared, 2) specific to the problem you are reporting, and 3) it is reasonable to expect the caller to deal with a checked exception for this2.

However explicitly declaring or throwing java.lang.Exception is almost always bad practice.

You should pick an exception class that matches the exceptional condition that has occurred. If you throw Exception it is difficult for the caller to separate this exception from any number of other possible declared and undeclared exceptions. This makes error recovery difficult, and if the caller chooses to propagate the Exception, the problem just spreads.


1 - Some people may disagree, but IMO there is no substantive difference between this case and the case of throwing exceptions in methods. The standard checked vs unchecked advice applies equally to both cases.

2 - For example, the existing FileInputStream constructors will throw FileNotFoundException if you try to open a file that does not exist. Assuming that it is reasonable for FileNotFoundException to be a checked exception3, then the constructor is the most appropriate place for that exception to be thrown. If we threw the FileNotFoundException the first time that (say) a read or write call was made, that is liable to make application logic more complicated.

3 - Given that this is one of the motivating examples for checked exceptions, if you don't accept this you are basically saying that all exceptions should be unchecked. That is not practical ... if you are going to use Java.


Someone suggested using assert for checking arguments. The problem with this is that checking of assert assertions can be turned on and off via a JVM command-line setting. Using assertions to check internal invariants is OK, but using them to implement argument checking that is specified in your javadoc is not a good idea ... because it means your method will only strictly implement the specification when assertion checking is enabled.

The second problem with assert is that if an assertion fails, then AssertionError will be thrown, and received wisdom is that it is a bad idea to attempt to catch Error and any of its subtypes.


I have never considered it to be a bad practice to throw an exception in the constructor. When the class is designed, you have a certain idea in mind of what the structure for that class should be. If someone else has a different idea and tries to execute that idea, then you should error accordingly, giving the user feedback on what the error is. In your case, you might consider something like

if (age < 0) throw new NegativeAgeException("The person you attempted " +
                       "to construct must be given a positive age.");

where NegativeAgeException is an exception class that you constructed yourself, possibly extending another exception like IndexOutOfBoundsException or something similar.

Assertions don't exactly seem to be the way to go, either, since you're not trying to discover bugs in your code. I would say terminating with an exception is absolutely the right thing to do here.


As mentioned in another answer here, in Guideline 7-3 of the Java Secure Coding Guidelines, throwing an exception in the constructor of a non-final class opens a potential attack vector:

Guideline 7-3 / OBJECT-3: Defend against partially initialized instances of non-final classes When a constructor in a non-final class throws an exception, attackers can attempt to gain access to partially initialized instances of that class. Ensure that a non-final class remains totally unusable until its constructor completes successfully.

From JDK 6 on, construction of a subclassable class can be prevented by throwing an exception before the Object constructor completes. To do this, perform the checks in an expression that is evaluated in a call to this() or super().

    // non-final java.lang.ClassLoader
    public abstract class ClassLoader {
        protected ClassLoader() {
            this(securityManagerCheck());
        }
        private ClassLoader(Void ignored) {
            // ... continue initialization ...
        }
        private static Void securityManagerCheck() {
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkCreateClassLoader();
            }
            return null;
        }
    }

For compatibility with older releases, a potential solution involves the use of an initialized flag. Set the flag as the last operation in a constructor before returning successfully. All methods providing a gateway to sensitive operations must first consult the flag before proceeding:

    public abstract class ClassLoader {

        private volatile boolean initialized;

        protected ClassLoader() {
            // permission needed to create ClassLoader
            securityManagerCheck();
            init();

            // Last action of constructor.
            this.initialized = true;
        }
        protected final Class defineClass(...) {
            checkInitialized();

            // regular logic follows
            ...
        }

        private void checkInitialized() {
            if (!initialized) {
                throw new SecurityException(
                    "NonFinal not initialized"
                );
            }
        }
    }

Furthermore, any security-sensitive uses of such classes should check the state of the initialization flag. In the case of ClassLoader construction, it should check that its parent class loader is initialized.

Partially initialized instances of a non-final class can be accessed via a finalizer attack. The attacker overrides the protected finalize method in a subclass and attempts to create a new instance of that subclass. This attempt fails (in the above example, the SecurityManager check in ClassLoader's constructor throws a security exception), but the attacker simply ignores any exception and waits for the virtual machine to perform finalization on the partially initialized object. When that occurs the malicious finalize method implementation is invoked, giving the attacker access to this, a reference to the object being finalized. Although the object is only partially initialized, the attacker can still invoke methods on it, thereby circumventing the SecurityManager check. While the initialized flag does not prevent access to the partially initialized object, it does prevent methods on that object from doing anything useful for the attacker.

Use of an initialized flag, while secure, can be cumbersome. Simply ensuring that all fields in a public non-final class contain a safe value (such as null) until object initialization completes successfully can represent a reasonable alternative in classes that are not security-sensitive.

A more robust, but also more verbose, approach is to use a "pointer to implementation" (or "pimpl"). The core of the class is moved into a non-public class with the interface class forwarding method calls. Any attempts to use the class before it is fully initialized will result in a NullPointerException. This approach is also good for dealing with clone and deserialization attacks.

    public abstract class ClassLoader {

        private final ClassLoaderImpl impl;

        protected ClassLoader() {
            this.impl = new ClassLoaderImpl();
        }
        protected final Class defineClass(...) {
            return impl.defineClass(...);
        }
    }

    /* pp */ class ClassLoaderImpl {
        /* pp */ ClassLoaderImpl() {
            // permission needed to create ClassLoader
            securityManagerCheck();
            init();
        }

        /* pp */ Class defineClass(...) {
            // regular logic follows
            ...
        }
    }

I am not for throwing Exceptions in the constructor since I am considering this as non-clean. There are several reasons for my opinion.

  1. As Richard mentioned you cannot initialize an instance in an easy manner. Especially in tests it is really annoying to build a test-wide object only by surrounding it in a try-catch during initialization.

  2. Constructors should be logic-free. There is no reason at all to encapsulate logic in a constructor, since you are always aiming for the Separation of Concerns and Single Responsibility Principle. Since the concern of the constructor is to "construct an object" it should not encapsulate any exception handling if following this approach.

  3. It smells like bad design. Imho if I am forced to do exception handling in the constructor I am at first asking myself if I have any design frauds in my class. It is necessary sometimes, but then I outsource this to a builder or factory to keep the constructor as simple as possible.

So if it is necessary to do some exception handling in the constructor, why would you not outsource this logic to a Builder of Factory? It might be a few more lines of code but gives you the freedom to implement a far more robust and well suited exception handling since you can outsource the logic for the exception handling even more and are not sticked to the constructor, which will encapsulate too much logic. And the client does not need to know anything about your constructing logic if you delegate the exception handling properly.


This is totally valid, I do it all the time. I usually use IllegalArguemntException if it is a result of parameter checking.

In this case I wouldn't suggest asserts because they are turned off in a deployment build and you always want to stop this from happening, but they are valid if your group does ALL it's testing with asserts turned on and you think the chance of missing a parameter problem at runtime is more acceptable than throwing an exception that is maybe more likely to cause a runtime crash.

Also, an assert would be more difficult for the caller to trap, this is easy.

You probably want to list it as a "throws" in your method's javadocs along with the reason so that callers aren't surprised.


It is bad practice to throw Exception, as that requires anyone who calls your constructor to catch Exception which is a bad practice.

It is a good idea to have a constructor (or any method) throw an exception, generally speaking IllegalArgumentException, which is unchecked, and thus the compiler doesn't force you to catch it.

You should throw checked exceptions (things that extend from Exception, but not RuntimeException) if you want the caller to catch it.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to exception

Connection Java-MySql : Public Key Retrieval is not allowed How to print an exception in Python 3? ASP.NET Core Web API exception handling Catching FULL exception message How to get exception message in Python properly What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean? what does Error "Thread 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)" mean? Argument Exception "Item with Same Key has already been added" The given key was not present in the dictionary. Which key? sql try/catch rollback/commit - preventing erroneous commit after rollback

Examples related to constructor

Two constructors Class constructor type in typescript? ReactJS: Warning: setState(...): Cannot update during an existing state transition Inheritance with base class constructor with parameters What is the difference between using constructor vs getInitialState in React / React Native? Getting error: ISO C++ forbids declaration of with no type undefined reference to 'vtable for class' constructor Call asynchronous method in constructor? Purpose of a constructor in Java? __init__() missing 1 required positional argument