Difference between Throws in method signature and Throw Statements in Java

40,082

Solution 1

You are pretty much right on. Except for one thing I'll mention in a bit.

throws is as much a part of the method API as the name and the parameters. Clients know if they call that method, they need to handle that exception--by simply throwing it also or by catching it and handling it (which may in fact entail the throwing of another exception wrapping the original). throws is addressed at compile time.

throw is the actual act of letting the runtime know something bad happened--that the exceptional condition we were worried about has in fact taken place. So it needs to be dealt with at runtime.

But you weren't quite right when you said, "Throws in method signature should always appear if there exist a throw statement in the method." That is often true but not always. I could also call another method that throws an exception within my method, and if I don't catch it, my method needs to throw it. In that case, there is no explicit throw of the same exception by me.

The final point is that you only need to declare an exception in throws when the exception is a checked exception--meaning it is from the other side of the Exception class hierarchy from RuntimeException. Common checked exceptions are IOException and SQLException. Checked exceptions must be listed in the throws part of the method signature if you don't handle them yourself. Anything subclassing RuntimeException--like NoSuchElementException in your example and also the hated NullPointerException--is an unchecked exception and doesn't have to be caught or thrown or anything.

Typically, you use checked exceptions for recoverable problems (where the client knows what can happen and can gracefully handle the problem and move on) and unchecked exceptions for catastrophic problems (like can't connect to the database).

If you can get past all the AOP stuff, this is a great discussion of how you use checked and unchecked exceptions effectively.

Solution 2

Vidya provided great answer to your questions.

The most important words are "The final point is that you only need to declare an exception in throws when the exception is a checked exception"

Just to show you an example code what does this mean. Imagine that we would like to use FileOutputStream in order to pass some data. The function would look like this:

public void saveSomeData() throws IOException {
  FileInputStream in = null;
  FileOutputStream out = null;

  try {
    in = new FileInputStream("input.txt");
    out = new FileOutputStream("output.txt");
    int c;

    while ((c = out.read() != -1) {
      in.write(c);
    }
  } catch (Exception e) {
    e.printStackTrace();
  } finally {
    // Close in
    if (in != null) {
      in.close(); // <-- If something bad happens here it will cause runtime error!
    }
    // Close out
    ...
  }
}

Now imagine, if you wouldn't provide throws IOException and something bad happens inside finally{} statement - it would cause an error.

Solution 3

throw attribute in method signature, like you correctly guessed, is a hint to the compiler that the method raises an exception that must be caught by the caller. This kind of exception, namely called checked exception is something that the caller MUST always catch or dispatch to its caller again. This is something at compiler level, the signature specifies which exception the method is able to throw: this enforces a try-catch or re-dispatch in the caller and a throw statement somewhere inside the method, is a constraint that the developer places to specify something about the method behavior.

On the other hand other exceptions, namely unchecked or runtime exceptions, (NoSucheElementException is one example) are exceptions which you are not forced to specify becuase they arise from different situations.

The conceptual difference is that checked exception are usually used to warn about exceptional situation which should be handled somehow (think about IOException) by the developer, while unchecked are real errors (like NullPointerException or like in your example NoSuchElementException)

Solution 4

RuntimeExceptions dont have to be handled in try-catch block so they dont have to be declared as thrown and NoSuchElementException is RuntimeException because it extends it.

Share:
40,082

Related videos on Youtube

Weishi Z
Author by

Weishi Z

Updated on July 09, 2022

Comments

  • Weishi Z
    Weishi Z almost 2 years

    I am trying to make it clear of the difference between Throws in method signature and Throw Statements in Java. Throws in method signature is as following:

    public void aMethod() throws IOException{
        FileReader f = new FileReader("notExist.txt");
    }
    

    Throw Statements is as following:

    public void bMethod() {
        throw new IOException();
    }
    

    From my understanding, a throws in method signature is a notification that the method may throw such an exception. throw statement is what actually throw a created object under according circumstances. In that sense, throws in method signature should always appear if there exist a throw statement in the method.

    However, the following code doesn't seem doing so. The code is from the library. My question is why it is happening? Am I understanding the concepts wrong?

    This piece of code is a copy from java.util.linkedList. @author Josh Bloch

     /**
     * Returns the first element in this list.
     *
     * @return the first element in this list
     * @throws NoSuchElementException if this list is empty
     */
    public E getFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }
    

    Update on the answer:

    update 1 : is above code the same as the following?

    // as far as I know, it is the same as without throws
    public E getFirst() throws NoSuchElementException {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }
    

    update 2 : For checked exception. Do I need to have "throws" in the signature? Yes.

    // has to throw checked exception otherwise compile error
    public String abc() throws IOException{
        throw new IOException();
    }
    
    • Bruno Reis
      Bruno Reis over 10 years
      Just a tiny correction: the throw statement doesn't create the throwable object; it simply throws an object that has already been created. It is the new keyword that creates an object. Think of throw new MyException() as throw (new MyException()). You could also have MyException e = new MyException(); throw e. See the difference? throw throws, new creates an instance.
  • Diffy
    Diffy almost 10 years
    What is the use of listing checked exceptions in 'throws' if we are not handling them? Are they automatically caught? And in case of NullPointerException, why doesnt have have to be caught? I can get this at runtime and we can catch it and give a simple error message?
  • Diffy
    Diffy almost 10 years
    So how are the RunTimeExceptions handled. Shouldn't we handle NullPointerException and RunTimeException?
  • Pshemo
    Pshemo almost 10 years
    @Diffy You can handle these kind of exception with try-catch but most ofthen it is better to just let them stop application since they most probably represent bug in code which needs to be corrected.
  • Kkov
    Kkov over 9 years
    A NullPointerException would imply there is a bug in your code. You should never allow them to happen ideally.