2

I am a c++ developer and I am pretty new with the checked and unchecked exception in java. The exception specifications in c++ are simply not good and that's why nobody is using it. I like the checked exception and I have a question, let's have this interface:

public interface Warehouse {
   MyStuff fetch(int id);
}

The warehouse can be implemented in different way: file, database or in memory (mock object for test).

Now, if I want to implement using a file, I cannot try to open the file in the method otherwise my signature will change and my class will not implement the interface anymore. Also if I had another class with another checked exception all the other existing implementation will be affected.

I can see two solutions:

  1. Catch the checked exception and throw another custom runtime exception. I don’t think this is a good solution, why the user should catch a runtime exception saying that a file is missing when there is already a standard and checked way to do that.

  2. Do the entire job in the constructor of the implementation class and leave the fetch function unable to throw. I like this way, the object both exists and is valid or it doesn’t exist. The only drawback on this approach is that we cannot implement a lazy evaluation; we need to read and parse the file in the constructor even though nobody will use the object. This is not efficient.

Am I missing something? Is there a better way to avoid this problem?

skaffman
  • 398,947
  • 96
  • 818
  • 769
Alessandro Teruzzi
  • 3,918
  • 1
  • 27
  • 41
  • Uhoh, checked vs. unchecked exceptions. That's gonna generate a lot of discussion. It's quite a religious topic among Java developers. – tobiasbayer Dec 21 '11 at 11:45

4 Answers4

2

Your first solution is the right one. Change your interface to :

public interface Warehouse {
    MyStuff fetch(int id) throws FetchFailureException;
}

And make every subclass wrap its IO, JDBC or whatever exception inside a FetchFailureException. This FetchFailureException exception should be runtime if unrecoverable, and checked if recoverable.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Ok, I didn't know you could create a checked exception. I see your point, however it is not going to proliferate the numbers of exception classes? – Alessandro Teruzzi Dec 21 '11 at 12:23
  • It will if you have lots of different situations like this where a single interface is used to target multiple data sources, each throwing a different kind of exception. This is not so frequent. And I prefer having to deal with one kind of exception (FetchFailureException) rather than N (IO, SQL, Memory...) – JB Nizet Dec 21 '11 at 12:28
0

Personally, I would have Warehouse list all the exceptions it can throw (including unchecked ones in the javadoc)

If you have an exception which is not listed, you need to handle it or wrap it. (Whether its checked or not)

You have to make your mind up whether you want Warehouse to throw an checked exception or not. You can't have it both ways. (Actually you can but its not a good idea as you can blindly throw a checked exception without the compiler knowing)

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

The Best practice is to specify the exceptions which the method will be throwing in the interface.

Suppose you have a custom Exception class :

class MyException extends Exception
{
public MyException (String message)
{ super(message);
}

public MyException (String message, Exception cause)
{
super(message, cause);
}

}

Handle all your exceptions in MyException class,

Now you can specify the exception which your method should throw in the interface

public Interface Warehouse
{

public MyStuff fetch() throws MyException;

}

Rajesh Pantula
  • 10,061
  • 9
  • 43
  • 52
0

I would suggest you to include in the Warehouse class all the exceptions and then working with subinterfaces in order to work with non checked exceptions, like this:

public interface Warehouse {
  MyStuff fetch(int id) throws FileNotFoundException;;
}

public interface FileWarehouse extends Warehouse {
  @Override
  MyStuff fetch(int id) throws FileNotFoundException;
}

public interface OtherWarehouse extends Warehouse {
  @Override
  MyStuff fetch(int id);
}
loscuropresagio
  • 1,922
  • 15
  • 26
  • If you have 1000 places using the Warehouse, and you introduce an additional subclass which throws a SQLException and not a FileNotFoundException, you'll have to fix 1000 compilation errors. If you use a domain-specific exception like FetchFailureException, and wrap every possible exception inside it, you don't have this problem anymore. – JB Nizet Dec 21 '11 at 12:11