简体   繁体   中英

Interface implementation launches different exceptions

I have an interface

public interface DataDAO {
     public void doSomething() throws Exception;
}

Lets say that there are two implementations, one that uses Database to get the data and another one that uses a Webservice.

public class DataDAOJdbc implements DataDAO {
    public void doSomething() throws Exception {
         //Implement
    }
}

public class DataDAOWebService implements DataDAO {
    public void doSomething() throws Exception {
         //Implement
    }
}

As you can already see, the problem is the super generic exception launched. As both implementations need to raise the same kind of exception.

The Jdbc implementation really only raises lets say SQLException while the Webservice implementation only rises the IOException.

Question is, how can I make the interface more elegant, so I capture a proper exception?

The first thing that I though was creating my own exception, and declare it on the interface level

public interface DataDAO {
  public void doSomething() throws MyCoolException;
}

And then, of course implement accordinly.

Question is, does this make sense? I have never created my own exceptions, so I am not really sure if this makes much sense or not. Also, what should I take into account when creating MyCoolException?

The first thing that I though was creating my own exception, and declare it on the interface level (...) does this make sense?

Yes, it does makes sense and I would think it is the best way to handle these situations.

I'll provide a kickoff example for this (based on your current code):

public class MyCoolException extends Exception {
    public MyCoolException() {
    }
    public MyCoolException(String message) {
        this.message = message;
    }
}

public interface DataDAO {
    public void doSomething() throws MyCoolException;
}

public class DataDAOJdbc implements DataDAO {
    public void doSomething() throws MyCoolException {
         //Implement
         try {
         } catch (SQLException e) {
             //handle the exception
             logger.error("Error!", e);
             //throw your custom exception
             throw new MyCoolException(e.getMessage());
         }
    }
}

public class DataDAOWebService implements DataDAO {
    public void doSomething() throws MyCoolException {
         //Implement
         try {
         } catch (IOException e) {
             //handle the exception
             logger.error("Error!", e);
             //throw your custom exception
             throw new MyCoolException(e.getMessage());
         }
    }
}

You can use a generic type to define the interface thrown:

public interface DataDAO<E extends Throwable> {
  public void doSomething() throws E;
}

Then your Implementations would look like this:

public class DataDAOJdbc implements DataDAO<JDBCException> {
    public void doSomething() throws JDBCException {
         //Implement
    }
}

public class DataDAOWebService implements DataDAO<WebServiceException> {
    public void doSomething() throws WebServiceException {
         //Implement
    }
}

However, this has the drawback that you can no longer handle all the exceptions the same way, unless you just catch Exception (which pretty much negates the entire point).

does this make sense?

Yes, it does. By declaring that doSomething throws a specific checked exception, you're signaling to callers of the method that they only need to catch and deal with that specific exception. By declaring plain throws Exception , callers would be encouraged to catch and deal with all Exception s, which even include runtime exceptions like NullPointerException .

what should I take into account when creating MyCoolException?

It could be as simple as the following:

public final class MyCoolException extends Exception {

    public MyCoolException(Throwable cause) {
        super(cause);
    }
}

So your custom exception would simply act as a wrapper for the cause exception, whatever it may be. If possible you could add a message with additional information that might be helpful for debugging. When MyCoolException is caught you can unwrap it by calling getCause() , or else pass it into a call to a logging framework (its stacktrace will include the cause exception).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM