Can constructors throw exceptions in Java?
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).
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.