233

Are constructors allowed to throw exceptions?

Mahmoud Hanafy
  • 7,958
  • 12
  • 47
  • 62

6 Answers6

362

Yes, constructors can throw exceptions. Usually this means that the new object is immediately eligible for garbage collection (although it may not be collected for some time, of course). It's possible for the "half-constructed" object to stick around though, if it's made itself visible earlier in the constructor (e.g. by assigning a static field, or adding itself to a collection).

One thing to be careful of about throwing exceptions in the constructor: because the caller (usually) will have no way of using the new object, the constructor ought to be careful to avoid acquiring unmanaged resources (file handles etc) and then throwing an exception without releasing them. For example, if the constructor tries to open a FileInputStream and a FileOutputStream, and the first succeeds but the second fails, you should try to close the first stream. This becomes harder if it's a subclass constructor which throws the exception, of course... it all becomes a bit tricky. It's not a problem very often, but it's worth considering.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 32
    +1. No one usually thinks of exceptions thrown by subclasses. – Vineet Reynolds Sep 03 '09 at 05:38
  • 1
    @JonSkeet: **Can you please give us some code example about** *if it's made itself visible earlier in the constructor (e.g. by assigning a static field, or adding itself to a collection).*? – Tarik Jan 03 '15 at 18:36
  • 4
    @Tarik: Well the code example would do exactly that - e.g. `someStaticField = this;` or `someCollection.add(this)` within a constructor. – Jon Skeet Jan 03 '15 at 18:48
  • 3
    @jonSkeet, Syntactically a constructor can throw and can declare that it can throw. However, should a constructor throw? What is the best practice here? – virusrocks May 16 '15 at 17:42
  • @JonSkeet I'd like to ask you about throwing exceptions for validation purposes, to impose class invariants. If someone tries to construct the object with a List of inaproppriate values I throw the IllegalArgumentException from the constructor. Is it correct ot do so? – St.Antario Jul 17 '15 at 07:34
  • @St.Antario: Yes, that sounds entirely reasonable. – Jon Skeet Jul 17 '15 at 07:37
  • What can be the case when called can have access to the partially created object? – Anmol Gupta Oct 12 '15 at 18:36
  • @AnmolGupta: What do you mean by "what can be the case"? I'm not sure what you're asking. – Jon Skeet Oct 12 '15 at 23:32
  • oh, As you mentioned that the caller ('usually') will have no way of using the new object. So, can there be a case when caller may use that object? Is it same as the example which you gave to Tarik? – Anmol Gupta Oct 13 '15 at 06:08
  • @AnmolGupta: Yes, exactly. – Jon Skeet Oct 13 '15 at 11:04
  • 1
    @JonSkeet "if it's made itself visible earlier in the constructor". As you're almost suggesting: incomplete objects should not be available. For this reason making an object visible beyond the scope of the constructor before having constructed it successfully is considered bad practice. – dexter Apr 13 '16 at 10:06
  • 6
    @baris.aydinoz: Completely disagree. If you provide invalid arguments to a constructor, I'd *expect* it to throw - not doing so would be the smell at that point. – Jon Skeet Sep 08 '16 at 08:15
  • The problem is how to write unit tests for cases in which Constructors throw exceptions? Mockito can only test methods and I don't see how developers should be forced to refactor or to use Powermock – Ghilteras Nov 10 '18 at 07:40
  • @Ghilteras: I don't see where mocking comes into it at all. You test it by asserting that when you call the constructor, an exception is thrown. It's a while since I've written Java so I don't know what the most idiomatic syntax would look like for that now, but in C# you'd do something like: `Assert.Throws(() => new SomeType(null));` – Jon Skeet Nov 10 '18 at 08:41
  • Mocking comes always into play since writing unit tests for your code is considered good practice. If you have to write tests for a constructor that throws an exception you cannot mock it to not throw it in Java without refactoring your code and have the constructor not throw,, which is not ideal. Since throwing exceptions in constructors is common i would have expected a testing framework that would support that. – Ghilteras Nov 10 '18 at 17:25
  • 1
    @Ghilteras: No, mocking *doesn't* always come into play just because you need to write unit tests. Look at the tests for [Noda Time](https://github.com/nodatime/nodatime) for example. Hardly *any* of those tests (of which there are many thousand) use mocks. It's still not clear to me where you expect the mocking to come in - you normally mock an *interface* (or abstract class), mocking the behavior of an existing instance (which is often passed *into* constructors). – Jon Skeet Nov 10 '18 at 19:03
  • Integration tests can be mock free, but Unit tests normally use mocks extensively and AFAIK write unit tests for your code is common practice (hence why I think mocks are fundamental and always come into play). It feels weird to have to justify why mocks are important to be honest. Anyway, as for the use case you still don't see I'd say take a class that initiate a connection and if the server is not reachable the constructor throws an exception. A clear example of this is Unbounid LDAP sdk. You cannot easily test the implementation as you can't mock a constructor to not throw an exception. – Ghilteras Nov 10 '18 at 19:44
  • @Ghilteras: Mocking is about *dependencies*, which is at the heart of both aspects here. If you're testing code that has no dependencies, you don't need any mocks. Even when you do need test doubles, I personally usually prefer fakes over mocks, but that's a different matter. But in terms of constructors: if your code is directly instantiating its dependencies rather than either accepting them as parameters or accepting a provider, of some kind, your code isn't amenable to testing. That's independent of whether the constructor for the dependency might throw an exception. – Jon Skeet Nov 11 '18 at 06:29
  • It's actually very common for code to directly instantiate dependencies through class constructors, not just in Java. I'm not sure what you mean when you say to accept deps as params or provider. Anyway the purpose of my initial comment was simply that I'd rather write code that does not rely on constructors throwing exceptions instead of encourage it because it makes it harder for me to test it with Mockito unless you are willing to refactor or do code gymnastics. – Ghilteras Nov 12 '18 at 21:02
  • 2
    @Ghilteras: Whereas I'd definitely rather express errors through the language-idiomatic way of expressing them: which is through exceptions in Java. To my mind, avoiding that idiom is where code gymnastics come in. Likewise mocking is far more effective when you've already used dependency injection rather than calling the constructor within the code. After all, when you call a constructor you're constraining yourself to *that* implementation, whereas the point of mocking is generally to mock an *interface* or abstract class, rather than using the implementation class at all. – Jon Skeet Nov 12 '18 at 21:09
79

Yes, they can throw exceptions. If so, they will only be partially initialized and if non-final, subject to attack.

The following is from the Secure Coding Guidelines 2.0.

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).

Billy Bob Bain
  • 2,894
  • 18
  • 13
  • 1
    Does this means throwing from non-final class is a security breach? Is this still an issue? – kroiz Feb 01 '15 at 21:35
  • 1
    Note that this guideline is only relevant if your code is, or is likely to be used in a context where security is important. For example, most Java code is used in contexts where there is no SecurityManager. – Stephen C Jan 16 '16 at 00:12
  • 1
    This problem can be circumvented by checking *before* calling the super constructor. As when you throw at this point, `finalize()` will never be called. Further, you should always check all values before assigning any values to instance fields, as that way, “partially initialized” mean “unusable”, hence, no security risk. – Holger Jun 05 '18 at 06:26
36

Absolutely.

If the constructor doesn't receive valid input, or can't construct the object in a valid manner, it has no other option but to throw an exception and alert its caller.

Yuval
  • 7,987
  • 12
  • 40
  • 54
15

Yes, it can throw an exception and you can declare that in the signature of the constructor too as shown in the example below:

public class ConstructorTest
{
    public ConstructorTest() throws InterruptedException
    {
        System.out.println("Preparing object....");
        Thread.sleep(1000);
        System.out.println("Object ready");
    }

    public static void main(String ... args)
    {
        try
        {
            ConstructorTest test = new ConstructorTest();
        }
        catch (InterruptedException e)
        {
            System.out.println("Got interrupted...");
        }
    }
}
V_Singh
  • 729
  • 11
  • 22
12

Yes, constructors are allowed to throw exceptions.

However, be very wise in choosing what exceptions they should be - checked exceptions or unchecked. Unchecked exceptions are basically subclasses of RuntimeException.

In almost all cases (I could not come up with an exception to this case), you'll need to throw a checked exception. The reason being that unchecked exceptions (like NullPointerException) are normally due to programming errors (like not validating inputs sufficiently).

The advantage that a checked exception offers is that the programmer is forced to catch the exception in his instantiation code, and thereby realizes that there can be a failure to create the object instance. Of course, only a code review will catch the poor programming practice of swallowing an exception.

Vineet Reynolds
  • 76,006
  • 17
  • 150
  • 174
9

Yes.

Constructors are nothing more than special methods, and can throw exceptions like any other method.

Isaac
  • 15,783
  • 9
  • 53
  • 76
  • The important thing in your statement is "special methods". So they are not like any other method. Throwing an exception from a non-final class' constructor **could** create a security hole, so special care should be taken when deciding to do this. See the answer by @Billy above, with the extract from Java Secure Coding Guidelines. – Ajoy Bhatia Mar 04 '15 at 23:35