问题
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:
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.
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?
回答1:
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.
回答2:
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)
回答3:
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;
}
回答4:
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);
}
来源:https://stackoverflow.com/questions/8589190/checked-exception-specification-and-strategy-pattern