I am trying to add a custom throws
clause to a method definied by an interface. This is not possible. How could I bypass it? Here is some code:
private void sendRequestToService(final ModuleRequest pushRequest)
{
ServiceConnection serviceConnection = new ServiceConnection()
{
public void onServiceConnected(ComponentName name, IBinder service)
{
try
{
//some lines..
} catch (RemoteException e)
{
throw new RuntimeException(new UnavailableDestException()) ;
}
}
};
}
Any idea how I could throw my custom exception?
There are two types of exceptions, checked and unchecked. Any Throwable
is either one or the other.
An example of a checked exception is IOException
; probably the most (in)famous unchecked exception is NullPointerException
.
Any checked exceptions that a method may throw
must be declared in its throws
clause. When you @Override
a method (either implementing an interface
method or overriding an inherited method from a superclass), certain requirements must be met, and one of them is that the throws
clause must not cause a conflict. Simplistically speaking, subclasses/implementations can throw LESS, not MORE checked exceptions.
An unchecked exception is defined as RuntimeException
and its subclasses, and Error
and its subclasses. They do not have to be declared in a method's throws
clause.
So in this particular case, if you want to throw
a CustomException
in an implementation of an interface
method that does not list it in its throws
clause, you can make CustomException extends RuntimeException
, making it unchecked. (It can also extends
any subclass of RuntimeException
, e.g. IllegalArgumentException
or IndexOutOfBoundsException
may be more appropriate in some cases).
This will allow you to compile the code as you desire, but note that the choice between choosing checked vs unchecked exception should not be taken too lightly. This is a contentious issue for many, and there are many factors to consider other than just getting the code to compile the way you want it. You may want to consider a redesign of the interface
rather than having implementors throwing various undocumented unchecked exceptions not specified by the interface
contract.
A method that overrides or hides another method, including methods that implement
abstract
methods defined in interfaces, may not be declared tothrow
more checked exceptions than the overridden or hidden method.
If a redesign is impossible, then wrapping your CustomException
in a RuntimeException
(or its subclass) will "work". That is, instead of:
// ideal solution, not possible without redesign
@Override public static void someMethod() throws CustomException {
throw new CustomException();
}
//...
try {
someMethod();
} catch (CustomException e) {
handleCustomException(e);
}
You can, should you insist, do the following:
// workaround if redesign is not possible
// NOT RECOMMENDED!
@Override public static void someMethod() {
throw new RuntimeException(new CustomException());
}
//...
try {
someMethod();
} catch (RuntimeException e) { // not catch(CustomException e)
if (e.getCause() instanceof CustomException) {
handleCustomException((CustomException) e.getCause());
} else {
throw e; // preserves previous behavior
}
}
It needs to be reiterated that this is NOT a recommendable technique in general. You should fix the problem at the design level if at all possible, but barring that, this is indeed a possible workaround.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With