Suppose I have interface I and two classes A and B that implement it.
The implementation of method f of this interface in A throws one set of exceptions and the implementation in B throws another set. The only common ancestor of these exceptions is java.lang.Exception. Is it reasonable to declare f throwing java.lang.Exception in this case? Any other alternatives?
The reason why I am asking is that on the one hand java.lang.Exception seems too general to me and one the other hand listing all exceptions seems impractical considering possible other implementations.
Example:
interface I {
void f() throws Exception;
}
class A implements I {
public void f() throws IOException {}
}
class B implements I {
public void f() throws InterruptedException {}
}
The reason for using an interface is to abstract away the implementation details.
By throwing these exceptions, you're exposing implementation details that probably should be abstracted away.
Perhaps it would be best to define a new exception. Then each implementation of f() would catch the exceptions it knows about and throw the new exception instead so you'd have:
interface I {
void f() throws MyException;
}
class A implements I {
public void f() throws MyException {
try {
...
} catch (IOException e) {
throw new MyException(e);
}
}
}
class B implements I {
public void f() throws MyException {
try {
...
} catch (InterruptedException e) {
throw new MyException(e);
}
}
}
By wrapping the implementation exception, you're still exposing it to the caller and that can bite you when you're calling remote methods. In those cases you need to do more work to return useful information in a generic way.
Edit
There seems to be a bit of a dispute going on about the correct approach.
When we call f(), we'll need code like:
I instanceOfI = getI();
try {
instanceOfI.f();
}
catch ( /* What should go here ? */ )
It comes down to what is a good Exception class to put in the catch block.
With OP's original code we could catch Exception and then maybe try to see which subclass we have, or not depending on requirements. Or we could individually catch each subclass but then we'd have to add catch blocks when new implementations throw different exceptions.
If we used Runtime exceptions it would come to much the same thing except that we could alternatively defer the exception handling to a caller method without even giving the possibility of exceptions any thought.
If we used my suggestion of using a new, wrapped exception then this means we have to catch MyException and then try to see what additional information is available. This essentially becomes very like just using an Exception, but requires extra work for the limited benefit of having a bespoke exception that can be tailored to the purpose.
This seems a bit backward. You should be throwing exceptions that are relevant and possibly specific to your interface, or not at all. Change the implementations to wrap a common Exception class (although not Exception itself). If you can't deal with this you may want to wrap the Exceptions in the implementations with a RuntimeException.
You could just declare the exceptions you throw
void f() throws IOException, InterruptedException;
If you use a decent IDE, it will correct this for you. I just throw the exception in the method, which the IDE gives the optionsto add to the method clause and its interface.
Related
If I have a class called Boat, and if I write :
class Boat throws Exception
Inside my class I am using try catch block to catch ArithmeticException for instance.
What benefit there is to declare an exception versus not declaring an exception?
A class does not throw exceptions. Only methods do.
For some exceptions (checked exceptions that may occur in your code and that you do not catch) the compiler forces you to declare them.
You never have to declare RuntimeExceptions (such as ArithmeticException), but you can. This serves as documentation.
You can declare checked exceptions that your code does not throw. This makes it future-proof if you might later want to throw them, and also allows for subclasses to do such.
When declaring exceptions, you can go broad/generic (throws Exception or even throws Throwable), but it is generally better to be more specific. That gives the people using your code a better idea of what to expect. The whole purpose of having these many specific Exception classes is to make it easier to handle exceptions appropriately (and have the compiler enforce the fact that someone at least thought about doing that).
First classes won't throw Exception, only methods will throw
check this Example
class A
{
public A() throws Exception
{
int k=5/0;
}
}
public class B
{
public static void main(String[] args)
{
A a=new A();
}
}
When you run the above you'll get compile time error saying
Unhandled exception type Exception
because when ever methods throws exception , they are expected to handle by calling object, it is just like saying 'Hey somebody handle Exception', so the method calling it should handle the Exception , if they don't it will be a compile time error.
For the smooth execution of program, Exception thrown by method should be handle by calling method. Here is how you need to handle.
class A
{
public A() throws Exception
{
int k=5/0;
}
}
public class B
{
public static void main(String[] args)
{
try{
A a=new A();
}
catch(Exception e)
{
System.out.println("caught "+e);
}
}
}
Declaring Exception will allow your program to compile if any Exception can be determined by the compiler to "escape". It's primary purpose, though, is to document to the user of your method (and to their compilers) that it may throw an Exception.
As such, declaring Exception, vs declaring a more specific exception cause, is nullifying the benefits of the scheme -- cheating.
If you write something like that,
double x = 1/0;
System.out.print("hey");
it will give you an exception and your code is going to stop, will not print hey. But if you encapsulate it with try/catch, it will not stop.
try{
double x = 1/0;
}catch(ArithmeticException){}
System.out.print("hey");
This will print hey.
A java book used by one of the students that I tutor contains the following (Blue Pelican Java version 3.0.5b Charles Cook):
If you have a method that throws an IOException up to the next level in the calling chain, we should be aware that in addition to IOException being thrown to the next level, all its subclasses are also thrown to the next level in the chain.
This seems obviously false, but is it correct? A version of this statement was posed on the student's exam, and was supposed to be true.
Also, the following code seems to be a counterexample to the claim:
public class ExceptionsTester {
public static void main(String[] args) {
try {
throw new IOException();
} catch (FileNotFoundException e) {
System.out.println("Subclasses thrown");
} catch (IOException e) {
System.out.println("Subclasses not thrown");
}
}
}
Did the book mean: 'If a method declares it throws Exception, then all subclasses of Exception can be thrown by it'? Because that's true in Java, but it doesn't tell you anything about the behaviour of catching exceptions and their subclasses (as the other answer suggests)
It doesn't make any sense on multiple levels and as worded is completely false.
Throwing an IOException does precisely that, throws an IOException.
Subclasses of IOException won't be caught, because they're not thrown.
Catching a superclass of an exception will catch the exception (although in this case it's java.lang.Exception, of course).
I'm not convinced the author is stating that if (say) an IOException is thrown then all IOException subclasses are also thrown. Based on reading the previous sections I think he's trying to make the point that if something declares it can throw an IOException it also means that IOException subclasses can be thrown.
It's worded horribly, but I have a difficult time believing the author thinks IOException subclasses are thrown when an IOException is thrown–he correctly points out that subclasses must be caught before their less-specific superclasses immediately prior. I find it more likely there was either an editing issue or it was just poorly stated.
Well this is not correct. First of all this is a static method and static methods dont get passed to the sub classed. Second this one does not throw an exception. It only handles it. By throwing an exeption I think the book author meant was declaring the method with a throws keyword.
for example
class A {
void x() throws IOException {}
}
if :
class B extends A {
#overries
void x() {}
}
Even though the overriden method in B does not explicity throw it, anyone who uses the method in B must handle the IOException.
A a = new B();
a.x();
Compiler will complain. You must use
A a = new B();
try {
a.x();
} catch (Exception e) {}
So the bottomline is the author is correct in a way.
when coding. try to solve the puzzle:
how to design the class/methods when InputStreamDigestComputor throw IOException?
It seems we can't use this degisn structure due to the template method throw exception but overrided method not throw it. but if change the overrided method to throw it, will cause other subclass both throw it.
So can any good suggestion for this case?
abstract class DigestComputor{
String compute(DigestAlgorithm algorithm){
MessageDigest instance;
try {
instance = MessageDigest.getInstance(algorithm.toString());
updateMessageDigest(instance);
return hex(instance.digest());
} catch (NoSuchAlgorithmException e) {
LOG.error(e.getMessage(), e);
throw new UnsupportedOperationException(e.getMessage(), e);
}
}
abstract void updateMessageDigest(MessageDigest instance);
}
class ByteBufferDigestComputor extends DigestComputor{
private final ByteBuffer byteBuffer;
public ByteBufferDigestComputor(ByteBuffer byteBuffer) {
super();
this.byteBuffer = byteBuffer;
}
#Override
void updateMessageDigest(MessageDigest instance) {
instance.update(byteBuffer);
}
}
class InputStreamDigestComputor extends DigestComputor{
// this place has error. due to exception. if I change the overrided method to throw it. evey caller will handle the exception. but
#Override
void updateMessageDigest(MessageDigest instance) {
throw new IOException();
}
}
In this case, your super class is not meant to throw an exception.
This is a case where your subclass is thus throwing an exception which is not expected by the overlying software architecture. Thus you can :
update all subclasses to throw exceptions.
wrap the entire Digestor class framework in a new class system.
(simplest) maintain the current code and simply wrap any exceptions you wish to throw in a RuntimeException.
RuntimeExceptions are the idiomatic way to throw exceptions in java which are not checked by the compiler or by method signatures, which occur somewhat unexpectedly.
Your requirements are schizophrenic.
You've got to decide whether the DigestComputor.updateMessageDigest method can, or can not throw IOException. If you want that to be possible, then you must add it to the signature in the base class. That is the only way to force the caller to do something about an IOException. But the downside is that you also force callers of the other subclasses to handle the IOException ... which won't occur.
You cannot create a method override that throws checked exceptions that the overridden method does not. That would break subtype substitutability, and Java doesn't allow it.
It it like a fork in the road. You have to decide to go one way or the other. You can't go both ways at the same time.
However there is a compromise (sort of):
public abstract class Base {
public abstract void method() throws IOException;
}
public class A extends Base {
public void method() throws IOException {
//
}
}
public class B extends Base {
public void method() { // Doesn't throw!!!
//
}
}
Now, if the caller knows that it has an instance of B it can do something like this:
Base base = ...
B b = (B) base;
b.method(); // No need to catch or propagate IOException
(IIRC, the ability to do this ... i.e. to reduce the exceptions thrown in an overriding method ... was added in Java 1.5.)
As someone else suggested, the simplest thing to do would be to simple wrap the real exception in a runtime exception. As a result, you don't have to declare the exception in your throws clause. If you're ambitious enough you can make your own subclass of RuntimeException and catch it at a higher level (this is what hibernate does, it catches all SQLExceptions thrown and wraps them in some subclass of DataAccessException which is a runtime exception).
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.
References
JLS 11.2 Compile-Time Checking of Exceptions
JLS 8.4.6 Method Throws
A method that overrides or hides another method, including methods that implement abstract methods defined in interfaces, may not be declared to throw more checked exceptions than the overridden or hidden method.
Related questions
In Java, when should I create a checked exception, and when should it be a runtime exception?
When to choose checked and unchecked exceptions
The case against checked exceptions
See also
Effective Java 2nd Edition
Item 58: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
Item 59: Avoid unnecessary use of checked exceptions
Item 60: Favor the use of standard exceptions
Item 61: Throw exceptions appropriate to the abstraction
Item 62: Document all exceptions thrown by each method
Workaround "solution"
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.
Throw a RuntimeException.
Let's say I have the following Java interface that I may not modify:
public interface MyInterface {
public void doSomething();
}
And now the class implementing it is like this:
class MyImplementation implements MyInterface {
public void doSomething() {
try {
// read file
} catch (IOException e) {
// what to do?
}
}
}
I can't recover from not reading the file.
A subclass of RuntimeException can clearly help me, but I'm not sure if it's the right thing to do: the problem is that that exception would then not be documented in the class and a user of the class would possibly get that exception an know nothing about solving this.
What can I do?
We all agree: the interface is faulty.
Solution I chose
I finally decided to write a MyVeryOwnInterface that extends MyInterface and adds as part of the signature of the faulty methods the MyRuntimeException:
public interface MyVeryOwnInterface extends MyInterface {
public void doSomething() throws MyRuntimeException;
}
class MyImplementation implements MyVeryOwnInterface {
public void doSomething() throws MyRuntimeException {
try {
// read file
} catch (IOException e) {
throw new MyRuntimeException("Could not read the file", e);
}
}
}
You've encountered the problem of leaky abstractions. There is no really good solution, and using a RuntimeException pretty much the only thing you can do.
Arguably, this is also an example for why checked exceptions are a failed concept.
I'd throw a new IOError(e); and file an issue at the maintainer of the interface.
If you can't recover than you need to throw and thus wrap it into a RuntimeException or an Error and throw that.
public class Unchecked extends Error {
private final Exception source;
public Unchecked( Exception source) {
this.source = source;
}
public String toString() {
return "Unchecked Exception, Caused by: " + source;
}
public Exception getSource() {
return source;
}
public static Unchecked wrap( Exception cause ) {
return new Unchecked(cause);
}
}
Clearly the interface designer is at fault for not considering the possibility that doSomething() may fail. Ideally he should have either allowed IOException to be thrown (if he suspected that IO wouldbe invovled) or a SomethingException (checked) which you could use to wrap your IOException.
If the interface designer is available to you, talk to them and ask what they expected to happen in the case of failure. Maybe they can change the interface: or maybe it is acceptable to fail silently according to the interface's contract.
Failing all of these you are reduced to a choice of failing silently (possibly recording but not responding to the problem) or throwing a RuntimeException which may terminate the process.
I don't think there is anything to do except to declare throws IOException in the interface.
That is simply the nature of Java interfaces and checked exceptions.
You could have another method in your class (doSomethingDangerous) that throws the IOException. From the doSomething-implementation, you simply call doSomethingDangerous (wrapped in a try/catch) and then where ever you wish to be careful about doingSomething you call doSomethingDangerous directly.
I would suggest
throw new RuntimeException("while reading file " + fileName + "...", e);
Isn't the problem here, that the interface does not expect any problems at all?
(and you may want to create your own OurCompanyDomainException extends RuntimeException to make it easy to distinguish in the code on the other side of the interface).