Question

Assume InvalidResourceException is a subclass of ResourceException. Define two methods:

void handleException(ResourceException e) {
  System.out.println("ResourceException " + e.toString());
}
void handleException(InvalidResourceException e) {
  System.out.println("InvalidResourceException " + e.toString());
}

Now the following code:

try {
  throw new InvalidResourceException("invalid resource");
} catch (ResourceException e) {
  handleException(e);
}

prints this:

ResourceException: com.myPackage.InvalidResourceException: invalid resource

But the following code:

   try {
     throw new InvalidResourceException("invalid resource");
   } catch (InvalidResourceException e) {
     handleException(e);
   } catch (ResourceException e) {
     handleException(e);
   }

prints this:

InvalidResourceException:  com.myPackage.InvalidResourceException: invalid resource

This is with Sun's JDK 1.5.0_15.

Is this consistent with the Java standard?

What should this code do?

Exception e = new InvalidResourceException("invalid resource");
handleException(e);

What should this code do?

Exception e = new InvalidResourceException("invalid resource");
if (e instanceOf ResourceException) {
  handleException(e);
} else if (e instanceOf InvalidResourceException) {
  handleException(e);
} else {
  handleException(e):
}
Was it helpful?

Solution

Yes. It's correct. Overloads are always resolved statically.

Neither of your latter 2 examples will compile as e's static type is Exception, and neither of your overloads accept that type.

Edit:

Note that your final example isn't really a direct analog to the try/catch block. In the try/catch you have two variables called e: one for each catch, and their static types are InvalidResourceException and ResourceException respectively. In your final example you have a single variable named e, and its static type is Exception. If you added new variables and assigned to them with a cast then you'd get the same behavior as your try/catch (though you'd have to lose the final else branch).

OTHER TIPS

Regarding the first part of your question, the correct method to call is determined at compile time based on the type the variable is declared as. E.g. if you changed the catch statement to catch InvalidResourceException, then the handleException(InvalidResourceException) overload would be called instead.

Regarding the second part of your question, the JVM simply finds the first catch statement that is capable of handling the exception thrown. If you were to throw a ResourceException instead, then the second catch block would be executed.

The third part wont compile, as no suitable handleException() method exists to handle a plain Exception.

The last part will also fail to compile for the same reason as the third part.

You are expecting something called "double dispatch" which is not supported by java.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top