views:

774

answers:

5

In Java, what is the difference between the twin methods?

public void methodA() throws AnException {
    //do something
    throw new AnException();
}

public void methodA() {
    //do the same thing
    throw new AnException();
}

I have a intuition that it has something to do with being a well-designed method (because I put methodA in an interface, declared it the way methodA* does in its implementation and received a warning from Java that "A* cannot override A because A* doesn't throw AnException").

Is this speculation correct?

Is there any other subtle connotations in the two ways of doing things?

+7  A: 

If AnException is a checked exception (in other words, if it doesn't extend RuntimeException) then methodA won't compile. Checked exceptions must always be declated.

If AnException is an unchecked exception (if it does extend RuntimeException), then either is allowed by the java compiler, and either is interpreted equivalently by the java runtime. methodA is still probably still preferred in this case, for the reasons of documentation. The javadoc for your method will show that it might throw AnException. It's good to let users of your method know what Exceptions they should expect.

A: 

In the second method the AnException class need to be a subclass of RuntimeException which means that the declaration is not mandatory and the method callers don't have to handle it. An example of RuntimeException is ArrayOutOfBoundException, imagine if you would have explicitly handle the exception (by declaring a throws or with a try/catch block) every time you use a List.

Julien Grenier
A: 

For purely documentation reasons, it's good that the exception is included in the function definition. This way it's clear to callers what exceptions need to be handled. I'm also guessing that the compiler needs to do some advanced setup for functions that throw exceptions.

Dana the Sane
A: 

The first method must be called in try catch block or in method declaring throws AnException otherwise compilation will fail.

The second does not have such restriction

A: 

Aside from the good answers given by others about the compilability of your methods by themselves, there is the matter of implementing interfaces and overriding methods in super-classes.

The rule says that you can override/implement a method, but you cannot declare additional exception to those declared by the original method signature. To understand this, think of this example.

Let's say you're using some sort of data structure:

public abstract class AbstractBox {
  public abstract void addItem(Item newItem);
  public abstract void removeItem(Item oldItem);
}

You have your own implementation, but you decide to declare exceptions that do not appear in the original signature:

public class MyBox extends AbstractBox {
  public void addItem(Item newItem) throws ItemAlreadyPresentException {...}
  public void removeItem(Item oldItem) throws NoSuchItemException {...}
}

Now let's consider this generic code that handles Box objects, and receives an instance of MyBox:

public void boxHandler(AbstractBox box) {
  Item item = new Item();
  box.removeItem(item);
}

Whoever wrote this code wasn't expecting any exceptions, nor did she intend to handle implementor exceptions. To prevent this, the compiler will not allow you to declare additional exceptions to those in the original signature.

Of course, if you handle exceptions internally... well, the compiler will be more than happy to allow you to drop declared exceptions from your signature ;-)

Hope this helps...

Yuval =8-)

Yuval
You cannot declare or throw additional checked exceptions. You can however throw additional undeclared unchecked exceptions and errors.
Peter Lawrey
Unchecked exceptions and errors are meant to be thrown without declaration, and represent situations where the using code has no viable handling options, and the application *should* crash. This is always true, nothing to do with overriding methods. =8-)
Yuval