4

So this is regarding an interview question I was recently asked. The interviewer started on this by asking me how we create our custom Exceptions. On answering that, he asked me how I'd create a RunTimeExceptions. I said we'd create them in the same way as we would create the checked Exceptions. Just our custom exception would extend from the RunTimeException class. Then he asked in what scenarios would you create your own RunTimeException. Now I couldn't think of a good answer to that. In none of my projects, we created custom RunTimeExceptions.

I also think that we should never create RunTimeExceptions. JVM can fail only in a finite number of ways and it handles them well. While writing an application we can't predict what runtime exceptions can occur and hence we shouldn't need to handle them. And if we can predict those conditions, they aren't RunTimeExceptions then. Since we neither need new runtime exceptions, nor need a handling of runtimeexceptions, why would we ever need to create a custom RunTimeException. Everything that we can pre-think of as a possible failure condition should be handled at compile time and it would be a checked exception. Right? Only the things that cannot be handled at compile time and the ones that depend on run time things go into the category of RunTimeExceptions.

Even if we write custom RunTimeExceptions and then a custom method that should throw that RunTimeException - how do we make sure that the method will throw that particular RunTimeException. How do we do that mapping. It doesn't seem possible to me.

Am I missing something/ many things here? Kindly advice.

Thanks, Chan.

Chan
  • 651
  • 2
  • 8
  • 15
  • Modern programming techniques recommend to use **unchecked** exceptions. You can read why, in the nice article [here](http://johnpwood.net/2008/04/21/java-checked-exceptions-vs-runtime-exceptions/). – agad Jul 31 '13 at 09:57

4 Answers4

6

I think the interviewer was trying to see if you understand the purpose of runtime exceptions, which is to signal programmer's errors (as opposed to application exceptions, which signal problems with the execution environment).

You can and you should create subclasses of RuntimeException whenever your method needs to signal a condition that amounts to a programming error, and you need to provide additional information regarding the error the exception describes.

For example, consider a class that lets you store data in a sparse multidimensional array. One of the APIs such class would probably provide is a getter that takes an array of indexes. The number of indexes needs to equal the number of dimensions in the array, and each index must be within its bounds. Supplying an array parameter that has an incorrect number of elements, or has one or more element outside its bounds, is a programming error. You need to signal it with a runtime exception. If you want to signal this error, and provide a full account of what went wrong, your subclass IllegalArgumentException, a subclass of RuntimeException, to build your own exception.

Finally, there is one more situation when you want to subclass RuntimeException: when you should provide a "regular" exception, but you do not want your users to wrap each call of your API in a try/catch block. In situations like these, you can replace a single method

void performOperation() throws CustomApplicationException;

with a pair of methods

boolean canPerformOperation();
void performOperation();

The first method tells the caller that it is safe to call the second method in the current state; it never throws an exception.

The second method fail only in the state when the first method returns false, making a failure a programming error, thus justifying the use of RuntimeException to signal such failures.

Ripon Al Wasim
  • 36,924
  • 42
  • 155
  • 176
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • I am way too inexperienced to comment on answers of legends like @JonSkeet or you Sir ! But the point is he can append his custom messages to the runtime exception , why create a new class ? – AllTooSir Jul 31 '13 at 10:10
  • 1
    @TheNewIdiot to be able to catch it if you want or easy handle it in another way – agad Jul 31 '13 at 10:12
  • @agad He can even catch the runtime ? Can't he ? – AllTooSir Jul 31 '13 at 10:13
  • 1
    @TheNewIdiot For the same reason the current subclasses of `RuntimeException` are created - to provide a more descriptive error report to your customers. For example, Java APIs could have been written without `IllegalArgumentException`, using `RuntimeException` with a custom message instead. This would have worked fine, but the reported errors would be less descriptive. – Sergey Kalinichenko Jul 31 '13 at 10:16
  • @TheNewIdiot Yes, but maybe want to handle just this known exception, not all RuntimeExceptions. To do that, without your own class you need to do something like that: try{ //try something } catch (RuntimeException e){ if ("my message".equals(e.getMessage()) { //do something } else {throw e}; – agad Jul 31 '13 at 10:17
  • Thanks a lot, Dasblinkenlight. That was a very nice explanation. – Chan Jul 31 '13 at 10:26
  • @dasblinkenlight, I'm in a situation where I'm updating a shared library and need to throw a new type of exception from a very deep layer of the library. If I do not throw a custom RuntimeException, the only alternative is a huge mess of non-backwards-compatible method signature changes and most likely a minor version bump. Because the exception is thrown as the result of a service call, I cannot use the "canDoX" model. The easiest thing to do is throw a custom RuntimeException and catch it upstream wherever I need it. What do you recommend for this situation? – sichinumi Mar 17 '17 at 01:48
  • @sichinumi This is a new question that would be of interest to other site visitors. Please post a new question, optionally referring to this one in its body, and explaining your situation. Something along the lines of "Adding an exception to a library without breaking backward compatibility". Feel free to reply to this comment with a link to your new question. – Sergey Kalinichenko Mar 17 '17 at 03:27
4

Checked Exception vs Unchecked Exception is a long time debate among Java developers. I'm not be here to ignite the fire, but only want to share with you how I use it in our work.

For example, another service call my server for customer information. The input is customerID, and I will return a customer object

// Web Service interface
public CustomerInfo getCustomerInformation(int customerId, int securityToken) {
   check(securityToken);
   Customer customer = merchantService.getCustomer(customerId);
   return customer.getInfo();
}

// MerchantService
public Customer getCustomer(int customerId) {
   return customerService.getCustomer(customerId);
}

What will happen if the system can't find a particular customer? Of course it will throw an exception or return null. But returning null is bad, since it will make you check null everytime calling from a service. So I go with throwing exception:

// Customer service
public Customer getCustomer(id) {
   Customer customer = getCustomerFromDB();
   if (customer == null) throw CustomerNotExistedException();
   return customer;
}

Now the question is whether CustomerNotExistedException is a Exception or a RuntimeException. If it's a checked exception, you will need to catch and process it at the function that calls getCustomer. That means you must catch it at MerchantService. However, all you want is to produce a 404 error at WebService level, so that catching it at MerchantService won't do anything more than throwing the exception again. It pollutes the code.

In the general case, I often use RuntimeException to let some exception "bubble up" to the level in which they can be processed.

For your reference, I would recommend the book Clean code from Robert C. Martin. It explains quite well how we should use exception to handle errors in Java.

Hoàng Long
  • 10,746
  • 20
  • 75
  • 124
1

You would create your own RuntimeException subclass if:

  • You don't want it to be a checked exception, because you don't expect callers to explicitly catch the exception. (Personally I believe that checked exceptions are rather overused in the standard library.)
  • You still want to provide more information than just a message (just the type itself is a helpful starting point in a log).

HibernateException is an example of this in the Hibernate ORM.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    If am not mistaken RuntimeExceptions are also used when the caller will not get any advantage on finding that exception is thrown, for maybe something not recoverable. – Narendra Pathai Jul 31 '13 at 09:58
  • @NarendraPathai: It depends on what you mean by "finding" that the exception is thrown. I explicitly cover callers not *catching* the exception in the first bullet. – Jon Skeet Jul 31 '13 at 11:01
0

I think when you are creating Custom Exceptions , please don't subclass RuntimeException , it defeats the whole purpose of creating the custom exception.

Even if we write custom RunTimeExceptions and then a custom method that should throw that RunTimeException - how do we make sure that the method will throw that particular RunTimeException.

The point here is actually the caller of the method needn't surround that in a try-catch block as it is not a checked exception. Unless you have a good reason to throw a custom unchecked exception , say , just to provide additional custom information for logging etc. don't do that. Another bad implementation will be sometimes you would to just want to catch the checked exceptions in your code and throw custom unchecked exceptions to get rid of all the try-catch in the caller code.

AllTooSir
  • 48,828
  • 16
  • 130
  • 164
  • 1
    In what way does it "defeat the whole purpose of creating the custom exception"? It sounds to me like you're considering compile-time checking to be the only benefit of creating exception subclasses, and I disagree with that. – Jon Skeet Jul 31 '13 at 09:50
  • Thanks. I thought so but since the interviewer asked me about it and since we had more than a 5 mins' discussion on it, I thought I'd check if any of my premises are fundamentally flawed or if I am missing something here. – Chan Jul 31 '13 at 09:53