Monday, October 29, 2018

In Java, when should I create a checked exception, and when should it be a runtime exception?










When should I create a checked exception, and when should I make a runtime exception?



For example, suppose I created the following class:



public class Account {
private float balance;

/* ... constructor, getter, and other fields and methods */

public void transferTo(Account other, float amount) {
if (amount > balance)
throw new NotEnoughBalanceException();
/* ... */
}
}


How should I create my NotEnoughBalanceException? Should it extend Exception or RuntimeException? Or should I just use IllegalArgumentException instead?


Answer



There's a LOT of disagreement on this topic. At my last job, we ran into some real issues with Runtime exceptions being forgotten until they showed up in production (on agedwards.com), so we resolved to use checked exceptions exclusively.



At my current job, I find that there are many who are for Runtime exceptions in many or all cases.



Here's what I think: Using CheckedExceptions, I am forced at compile time to at least acknowledge the exception in the caller. With Runtime exceptions, I am not forced to by the compiler, but can write a unit test that makes me deal with it. Since I still believe that the earlier a bug is caught the cheaper it is to fix it, I prefer CheckedExceptions for this reason.



From a philosophical point of view, a method call is a contract to some degree between the caller and the called. Since the compiler enforces the types of parameters that are passed in, it seems symmetrical to let it enforce the types on the way out. That is, return values or exceptions.



My experience tells me that I get higher quality, that is, code that JUST WORKS, when I'm using checked exceptions. Checked exceptions may clutter code, but there are techniques to deal with this. I like to translate exceptions when passing a layer boundary. For example, if I'm passing up from my persistence layer, I would like to convert an SQL exception to a persistence exception, since the next layer up shouldn't care that I'm persisting to a SQL database, but will want to know if something could not be persisted. Another technique I use is to create a simple hierarchy of exceptions. This lets me write cleaner code one layer up, since I can catch the superclass, and only deal with the individual subclasses when it really matters.


No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...