Throw & Throws - [OOP & Java #9]
Tags: computerscience, java, codenewbie
Published: 2020-10-20 00:05:03

### Exceptions
Exceptions are things that worth special consideration. This could mean that the execution of some method is "exceptional" because it might result in errors.

We, therefore, handle exceptions in our program to avoid errors.
There are two main branches of exceptions, checked and unchecked exceptions.

####<center> Summary </center>
| Exception | Checked                               | Unchecked                                    |
|------------|---------------------------------------|----------------------------------------------|
| Error      | Compile-time                          | Run-time                                     |
| Occurrence | Anticipate and handle                 | Unanticipated                                |
| Example   | IOException FileNotFoundException ... | NullPointerException ArithmeticException ... |
| Strategy   | Must declare or catch                 | Result in bugs to be fixed                   |

---
### Try-catch
One way to deal with known exceptions is to put dangerous code in a try-catch block.
```java 
try {
  // Might result in FileNotFoundException
  FileReader file = new FileReader(args[0]);
  // any other code that might result in exceptions
} catch (FileNotFoundException e) {
  // do something about the exception
}
```
When we catch an exception, we could resolve it by printing out some message to the caller, or we could simply throw the exception at the caller. Actively raising an exception is still considered a way of "handling" exceptions.
```java
try {
  // something dangerous here
} catch (IOException e) {
  // simply throw exceptions
  // can throw different exceptions
  throw new NullPointerException("My exception message here");
}
```
### Throw
The keyword **throw** is used to raise exceptions. It could be used within a catch block to resolve another exception. It could also be used whenever we would like to raise an exception.
```java
// some method
public void test() {
  throw new ArrayStoreException("Throwing it because I want to");
}
```
### Throws
Instead of using try-catch, we could simply declare in the method signature that this method could throw some exceptions that callers must look out for. Note that we **don't** declare unchecked/run-time exceptions because they cannot be anticipated.

---
Let's see some code examples.

```java
  // might throw unchecked exceptions, which is typical
  void willThrowUnchecked() {
    // does some stuff
    throw new NullPointerException("this is an unchecked exception");
  }

  // DON'T DO THIS, unchecked exceptions need not be declared 
  void willThrowUnchecked2() throws NullPointerException {
    throw new NullPointerException("this is an unchecked exception");
  }

  // might throw a checked exception
  void willThrowChecked() throws IOException {
    // pretend that it might throw an exception
    throw new IOException();
  }

  // DON'T DO THIS, checked exceptions must be declared
  // will not compile 
  void willThrowChecked2() {
    throw new IOException();
  }
```
---
Unchecked exceptions
- The function call within this method body does not throw checked exceptions, hence ok to not do any handling.
```java
  // will compile
  void useUnchecked() {
    willThrowUnchecked();
  }
```
- Unchecked exceptions need NOT be anticipated. No known checked exceptions anticipated. Hence ok to not do any handling.
```java
  // will compile
  void useUnchecked2() {
    willThrowUnchecked2();
  }
```
- We can handle unchecked exceptions, if we want to
```java
  // will compile
  void useUnchecked3() {
    try {
    willThrowUnchecked();
  } catch (NullPointerException e) {
     System.out.println("hello");
  }
}
```
---
Checked exceptions
- If we don't handle checked exceptions, we are not allowed to use potentially dangerous methods.
```java
  // will not compile
  void useChecked() {
    willThrowChecked();
  }
```
- We declare that the current method is dangerous, so whenever this method is called, the caller needs to handle it. we passed the responsibility to the caller of this method. This is considered "handling" exceptions as well.
```java
  // will compile
  void useChecked2() throws IOException {
    willThrowChecked();
  }
```
- We handled the exception using try-catch, safe and sound.
```java
  // will compile
  void useChecked3() {
    try {
      willThrowChecked();
    } catch (IOException e) {
      System.out.println("I handled it!");
    }
```
- We handled it by throwing another exception, still safe.
```java
  // will compile
  void useChecked4() {
    try {
      willThrowChecked();
    } catch (IOException e) {
      throw new NullPointerException("Hey there is a problem!");
    }
  }
```
- If we throw a checked exception as a response, we must declare it.
```java
  // will NOT compile
  void useChecked4() {
    try {
      willThrowChecked();
    } catch (IOException e) {
      throw new IOException ("Hey there is a problem!");
    }
  }

  // will compile
  void useChecked4() throws IOException {
    try {
      willThrowChecked();
    } catch (IOException e) {
      throw new IOException ("Hey there is a problem!");
    }
  }
```
---
### Throws vs Throw
The two keywords are not exactly comparable because they serve different purposes. They can co-exist in a single method. Hence, the usage of the two reserved words depend on the situation.

####<center> Summary </center>

|         | Throws                                                                       | Throw                                                                        |
|---------|------------------------------------------------------------------------------|------------------------------------------------------------------------------|
| Purpose | To declare checked exceptions                                                | To throw any exceptions                                                      |
| Usage   | when the method body contains code that might throw checked exceptions | As a way to raise exceptions (both checked and unchecked) to the caller |
| Example | `void test() throws IOException {}`                                          | `throw new NullPointerException("WRONG");`                                   |                                               |