3

I'm new to exceptions and this is what I know so far:

  • throws and throw are different

  • doing throw IllegalArgumentException I'll probably have to add throws IllegalArgumentException to the method signature

  • IllegalArgumentException is an unchecked exception and "Exceptions whose handling is not verified during Compile time"

Sources: http://javarevisited.blogspot.com/2011/12/checked-vs-unchecked-exception-in-java.html#ixzz2yM5jNFeg, http://www.tutorialspoint.com/java/java_exceptions.htm

This is a homework question: does throwing IllegalArgumentException make the program quit instantly?

The question seems a bit general and likely to be false, but I'm not entirely clear about IllegalArgumentException either. The sources did not really exemplify throw in a simple way, so I'm still confused. So, it would be great if there could be a simple explanation to this.

craigcaulfield
  • 3,381
  • 10
  • 32
  • 40
user3511965
  • 195
  • 1
  • 3
  • 9
  • If you call a method that expects a specific input but you don't obey then it might throw IllegalArgumentException. If any exception is not caught, your program will end. If it is caught by anyone up the call stack then it's up to the catcher on how to handle it. So if you anticipate your call might cause an IllegalArgumentException you are able to handle it in 2 ways. 1) check the variables yourself before calling to ensure they are good. 2) surround your call by a try block and catch the IllegalArgumentException and do something appropriate if it happens. – Always Learning Apr 09 '14 at 03:29
  • 1
    There are 2 types of Exceptions. "Checked Exception" and "Runtime Exception". You only need to declare `throws` clause in the method signature if the method throws a checked exception. For runtime exception (ie. IllegalArgumentException), you do not need to declare a throws clause in the method signature. Throwing an exception does not make a program quit instantly. You have a choice to catch it and handle that exception. – anonymous Apr 09 '14 at 03:29
  • @stvcisco I'm just assuming I'm calling 'throw IllegalArgumentException' and not doing a try-catch block. Does that exit the current method? Or even the whole program? I guess not, right? – user3511965 Apr 09 '14 at 03:30
  • Using 'throw' means you are declaring that an exception happened. This causes your current method to exit immediately. Whether your program ends depends on whether anyone in the call stack catches the exception as the call stack unravels back to main. If nobody catches it, the program ends. – Always Learning Apr 09 '14 at 03:32

2 Answers2

3

Throwing any exception makes the current method exit immediately, but not the whole program. Furthermore, the exception will continue being thrown at the calling method, from where the first method threw it; this is called propagation. Whether it keeps going at that point depends on whether that calling method catches the exception. If nothing catches the exception, it'll propagate all the way back to the main method (this is assuming a simple, single-threaded application), and if that method also throws it, then the program will exit.

void callee() {
    if (someTrueCondition()) {
        throw new IllegalArgumentException("whatever");
    }
    System.out.println("this will never get called");
}

void caller() {
    calle(); // the IllegalArgumentException propagates from here
    System.out.println("this will also never get called");
}

The above is true for any exception. What makes IllegalArgumentException different from others is only the fact that it's unchecked, and thus doesn't need to be declared in a throws clause on the method that may throw it. (Note that in your question, you said you probably would need to declare throws IllegalArgumentException, but you actually don't, because it's an unchecked exception.)

If you were instead throwing a checked exception (e.g., throw new SQLException()), then both callee and caller would need to declare that exception. callee would need to declare it because it throws that exception directly, and caller would need to declare it because it may throw that exception indirectly, via propagation from callee.

The only way to stop this propagation (both of the exception at runtime, and of the throws clauses at compile-time) is to catch the given exception with a try-catch.

yshavit
  • 42,327
  • 7
  • 87
  • 124
  • What if there is only a main function and we call the statement? Would it cause the program to quit? – user3511965 Apr 09 '14 at 03:41
  • Yes; if `main` throws an exception, the program halts (again, assuming a single-threaded application). – yshavit Apr 09 '14 at 03:46
  • Does halting equate to stopping? And do you think the question of whether it causes the program to quit immediately is too broad and general? – user3511965 Apr 09 '14 at 05:58
  • Yes, halting and stopping are the same. The question of whether it causes the program to quit immediately is a fine question to ask, but it's important to differentiate between an overly simple "yes" and a more in-depth "the program will quit, but here are the steps first (namely, the exception propagation)." The reason that's important is that those steps can be different in other programs (for instance, if the exception is caught), which will then lead to a different end result (like the program not immediately quitting). – yshavit Apr 09 '14 at 06:00
2

An uncaught exception can make a single threaded application quit. If you were to drop the foo/bar example below into a Java app, you will see that the execution state will terminate because of an uncaught exception.

Difference between throws & throw

/**
 * This is my foo method
 * @throws IllegalArgumentException if argument is wrong!
 */
public void foo(String s) throws IllegalArgumentException {
    // Some code
    if (!s.equals("bar")) {
        throw IllegalArgumentException("something not quite right here...");
    }
}

You are nearly there - @throws is for documentation purposes in commenting as well as use in the method signature to indicate any possible exceptions a method might throw. This includes exceptions it directly or indirectly throws. It's always good to add any throws that it chains or doesn't catch that can be thrown from any methods it uses from the same or other objects/classes.

Throw is the implementation code. IllegalArgumentException will typically be thrown when you try to send the wrong class type of an argument to the method at run time. You can also manually throw them any time a check fails, as demonstrated above.

Also, you don't need to declare it in the method signature, however if you do declare it, any implementing code you have should be wrapped in a try/catch block.

An example of an indirect exception:

class foo {
    /**
     * @throws IllegalArgumentException when s != foo
     */
    public void foo(String s) throws IllegalArgumentException {
        if (!s.equals("foo")) {
            throws IllegalArgumentException("argument did not equal 'foo'");
        }
    }
}

class bar {
    protected foo foo;
    public bar() {
        this.foo = new foo();
    }

    public void bar(String s) throws IllegalArgumentException {
        this.foo.foo(s);
    }
}
Justin Mitchell
  • 339
  • 1
  • 5
  • 1
    I don't think the OP was asking about `@throws` for documentation purposes. The scenario where a `throws` clause is needed in the method signature is when the method throws a `checked exception`. Try `throw new IOException("")` without the throws clause and you'll see the problem. – anonymous Apr 09 '14 at 03:38
  • Not quite... throw spec, not comment. – djechlin Apr 09 '14 at 03:38