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. Received wisdom is that it is a bad idea to attempt to catch Error and any of its subtypes. But irrespective of that, you are still throwing an exception, albeit in an indirect way.
Videos
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. Received wisdom is that it is a bad idea to attempt to catch Error and any of its subtypes. But irrespective of that, you are still throwing an exception, albeit in an indirect way.
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?
No, you don't "inherit" non-default constructors, you need to define the one taking a String in your class. Typically you use super(message) in your constructor to invoke your parent constructor. For example, like this:
public class MyException extends Exception {
public MyException(String message) {
super(message);
}
}
A typical custom exception I'd define is something like this:
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
public CustomException(String message, Throwable throwable) {
super(message, throwable);
}
}
I even create a template using Eclipse so I don't have to write all the stuff over and over again.
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.
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).
You should create all the Constructors you will use.
Don't add code when you imagine a use for something. Add it when you have a requirement for it.
http://c2.com/xp/YouArentGonnaNeedIt.html
It is not actually required to implement any particular constructor. One arbitrary can be implemented in order to construct the exception at all.
Usually two cases happen:
- Your code realizes that something went wrong after checking something. It wants to raise exception. For such case, a constructor that takes a string message is required. It is usually good to explain in the message that went wrong.
- Your code tries to do something and catches exception that cannot be thrown further as it is not declared. Then you still can explain that went wrong in the message, put some important context data there, but also it is vital to provide that catched exception for diagnostic. For such case, you need a constructor that takes String and Throwable.
I think, the version without parameters and the version that takes Throwable only are more for lazy people and you just enforce more order in your code by not implementing these.
If your specific exception benefit from some additional information that is always available, surely the constructor should have additional parameters, forcing to pass this information. In your case, a version with the two string parameters should be preserved but probably a version that also takes Throwable as a third parameter would be good. Many known exceptions (like IOException, for instance) went through the pain from "we will never need this kind of constructor" towards adding such constructor in the later versions.
I know its generally considered bad practice, but I have been using Objects.requireNonNull() for the constructor parameters, to ensure no null parameters are passed to my class. What does the community generally use?
Who says it is bad? You shouldn't be afraid to throw NullPointerException or IllegalArgumentException (or subclasses) from your constructor especially if your objects are immutable. Fail as early as possible so that the culprit is in the callstack and provide and explanation of the reason. It is also helpful to document the RuntimeExceptions you might throw.
For example with Objects.requireNonNull I have gotten in the habit of using the two arg variant and providing a message naming the argument being checked. Often when I get a stack track the source line number has changed slightly as a result of intervening chances from the version which generated the stack trace. Having the extra info of the parameter name really helps.
i worked on OpenJDK which spent a lot of effort to document which arguments could be null and the conditions under which exceptions are thrown. This documentation provides much of the basic for JCK tests. It is a lot of work to create documentation this thorough but I definitely came to appreciate the value of having that documentation when I found it missing with other APIs.
I know its generally considered bad practice
Where did you hear this? On the contrary, it is far better to throw a exception in the constructor than to return a malformed object that breaks things at time and place unrelated to the true source of the error.
Back on the days of Java 5, I wrote a method functionally identical to Objects.requireNonNull() for my employer at the time, and one of the main expected use-cases was constructors.