---
# System prepended metadata

title: 'Java Advanced Concepts - 2 [Exception Handling, Annotation]'

---

---
title: Agenda
description: 
duration: 250
card_type: cue_card
---

## Agenda

* Exception handling
    * Introduction of Exceptions
    * Erros
    * Good Practices with Exception
    * Throw vs Throws
    * Final, Finalize, Finally
    

> Give a brief about the agenda and what we are going to discuss in this session

---
title: Exception Handling
description: Introduction to Exceptions and What are they.
duration: 3600
card_type: cue_card
---

**Exception is basically an unitntentional event caused during the execution of program.**

Lets understand it with an example: 

```
function doSomething(int roll_no){
    // it perfroms some functions here.
}
```

Now for example I provided some roll_no that doesn't exist then this function won't be able to do anything and thus leading to an unexpected event. and telling the **caller function(parent)** that something bad has happened.

These unexpected events can be anything like: 

- **invalid roll_no**
- or, **network error while executing this function**.

Basically function is not ready to handle that or doesn't know how to handle that.

As we told that the **caller function** will see how to handle that.

**[Ask the Learners:]**
Is it mandatory for a caller function to handle the exception??

Ans-

Nope, as it is also possible that the caller function doesn't even know then it will call its parent(caller function.)

This is what the exceptions are. Now let's see there **types** and then we will be seeing thier implementation also.

---
title: Types of Exception
description: Different Types of Exception, which exception can be handled and which can't.
duration: 3600
card_type: cue_card
---

There are basically two types of exeptions bein defined: 

- **Compile Time Exception (Checked Exception)**
    - They are like basic exceptions, like file not found, network issue, etc
    - Checked exceptions are mandatory to be checked before build
    - Java forces you to check these errors
- **Run Time Exception (UnChecked Exception)**
    - Null pointer errors, out of bound errors
    - For example, X/Y is not having any errors, but what if user gives Y as 0, then it may break our code
    - Its upto developer to check

**[Note: ]** - **Run-time Exceptions should be as less as possible** because parent is not forced by compiler to acknwlodge that.

Now Let's understand the exceptions with their implementation: 

---
title: Exception Handling with Code
description: Implementing the Exceptions and how to handle them.
duration: 3600
card_type: cue_card
---

Let's say I created one file as : Doer.java like this: 

```java
package com.example.practice;
public class Doer {
    public void findStudentByRollNo(int roll){
        int c = roll/0;
    }
}
```

and called it in the Main file as: 

```java
package com.example.practice;
public class Main {
    public static void main(String[] args) {
        Doer doer = new Doer();
        doer.findStudentByRollNo(30);
    }
}
```

but since I am **dividing by 0**. I am getting the output as: 

![image](https://hackmd.io/_uploads/HkjmoGF5p.png)

**[Ask the learners:]**
But why the compiler didn't forced to hanlde this exception??

Ans- 
Beacuse these are the run-time exceptions. As we discussed above.

Okay now if I do, 

```java
package com.example.practice;

public class Doer {
    public Object findStudentByRollNo(int roll){
        if(roll < 30){
            return new Object();
        }
        throw new ClassNotFoundException(); 
    }
}
```

![image](https://hackmd.io/_uploads/SJvSnzYqT.png)

but the compiler is asking me to handle this one.beacuse it is a **compile-time exception.**

**[Note for instructor:]** If there is still any doubt about the run-time and compile-time exception clear that.

Now how to handle it : 

We can do so with this: 

```java
package com.example.practice;
public class Doer {
    public Object findStudentByRollNo(int roll) throws ClassNotFoundException{
        if(roll < 30){
            return new Object();
        }
        throw new ClassNotFoundException();
    }
}
```

and, now it **caller class** i.e. our **Main class** needs to handle it. So either it can handle that or it can also send further. 
So either by this: 

```java
package com.example.practice;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        Doer doer = new Doer();

        doer.findStudentByRollNo(30);
    }
}

```

or this: 

```
package com.example.practice;
public class Main {
    public static void main(String[] args) {
        Doer doer = new Doer();
        try {
            doer.findStudentByRollNo(30);
        }catch (ClassNotFoundException e){
            System.out.println(e);
        }
    }
}

```

We are basically trying to execute it and if not then the catching the exception that occurs.

**[Ask from Learners:]**
Can we handle multiple exceptions in one class.

Ans- yes we can this is how it will be done: 

Doer.java:

```
package com.example.practice;

import java.io.NotActiveException;
import java.util.Random;

public class Doer {
    public Object findStudentByRollNo(int roll) throws ClassNotFoundException,NotActiveException{
        if(roll < 30){
            return new Object();
        }

        Random r = new Random();
        int random = r.nextInt();

        if(random %2 == 0) throw new NotActiveException();

        throw new ClassNotFoundException();
    }
}
```
I included a **NotActiveException** and this is how it is being handled: 

```
package com.example.practice;
import java.io.NotActiveException;
public class Main {
    public static void main(String[] args) {
        Doer doer = new Doer();
        try {
            doer.findStudentByRollNo(30);
        }catch (ClassNotFoundException e){
            System.out.println(e);
        }catch (NotActiveException e){
            System.out.println(e);
        }

    }
}
```

So now lets understand the Hierarchy of Exceptions is detail manner.

---
title: Hierarchy of Exceptions and Erros
description: Understanding the Heirarchy of Exceptions and then what actually the Error is?
duration: 3600
card_type: cue_card
---

### Hierarchy of Exceptions

Till now we have studied about two exceptions : 

- Runtime Exception
- Compiletime Exception

**[Ask from learners: ]**
Are these two exceptions basically the two sibiling classes of each other??

Ans- **Not really.** 

Then how exactly the **hierarchy** of the exceptions in java. Lets check it:

It is something like this: 

![image](https://hackmd.io/_uploads/HJO5rv65T.png)

1. Everything in Java is a child of object. 
2. Then there is a class that extends the Object i.e. Throwable. 
3. This throwable has two variants:
    - Exception
    - Error
4. This Excpetion has a child which is a runtime Exception.
5. And if someone is just i.e. basically a **checked exception.**

**[Note for instructor:]** Explain the exceptions in detail manner.

### Errors:

Errors can be defined as the issues that are fratal which means there is no way  that java can run those programs later.

basically **Like the exceptions but that cannot be handled.**

For example: 

```
package com.example.practice;

public class Badthing {
    public static void call(int a) {
        call(a * a);
    }

    public static void main(String[] args) {
        Badthing.call(1);

    }
}
```
![image](https://hackmd.io/_uploads/S1os6Fpcp.png)

If we see clearly we are getting the error not an exception here basically.

**[Ask from Learners:]**

Can you catch an error??

Ans: **Yes you can catch an error but you shouldn't beacuse these are like the unexpected things.**

---
title: Throw and Throws
description: What are throw and throws keyword and what are differences between them.
duration: 3600
card_type: cue_card
---

### Throw:

Throw keyword is used when it has to indicate that exception has occured.

Used something like this:

![image](https://hackmd.io/_uploads/r1pHy56c6.png)

Whatever the exception is , be it a runtime exception or a compiletime exception, the throw keyword work is to indicate that exception has been occured.

### Throws

Throws keyword is used to declare that a particular method can through an exception which the caller should be careful of and check while using.

![image](https://hackmd.io/_uploads/rk5y9Aaqp.png)

**[Ask from Learners:]**
Which exception must be a part of throws?

Ans- Compile Time Exception.

**[Note for instructor:]** Explain the throw and throws keyword in a elaborative manner. So that student should have a clear idea of what they are actually.

---
title: Try-Catch and Finally
description: What is try-catch and thier implementation and where to use the finally keyword.
duration: 3600
card_type: cue_card
---

### What is try-catch and its importance.

For understanding the try-catch, lets first understand why it is needed.

Let's say that:

We have a method that can throw an exception.

**[Ask from Learners:]**
Till now what are the methods we have studied to handle it?

Ans: 
* Throw it ahead
* or, handle it using try/catch.

Let's discuss about the **throw it ahead one.**

```java
package com.example.practice;

import java.io.NotActiveException;

public class Main {
    public static void main(String[] args) {
        Doer doer = new Doer();
//        try {
//            doer.findStudentByRollNo(30);
//        }catch (ClassNotFoundException e){
//            System.out.println(e);
//        }catch (NotActiveException e){
//            System.out.println(e);
//        }
        
        doer.findStudentByRollNo(30);

    }
}
```

I commented out our previos try/catch to understand it and just calling the findStudentByRollNo() method.

This method is giving some error lets see that: 

![image](https://hackmd.io/_uploads/rJvhCAT9p.png)

**It says we have to handle the exceptions.**

Now I decided that I don't know how to handle these and want my parent to handle it. So how can we pass these exceptions to the parent. By using the throws keyword something like this: 

```java
package com.example.practice;

import java.io.NotActiveException;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException , NotActiveException {
        Doer doer = new Doer();
//        try {
//            doer.findStudentByRollNo(30);
//        }catch (ClassNotFoundException e){
//            System.out.println(e);
//        }catch (NotActiveException e){
//            System.out.println(e);
//        }

        doer.findStudentByRollNo(30);

    }
}
```

### Implementation

So now his parent will handle those and how that will be handling it is using the try-catch block. 

```java
package com.example.practice;

import java.io.NotActiveException;

public class Main {
    public static void main(String[] args) {
        Doer doer = new Doer();
        try {
            doer.findStudentByRollNo(30);
        }catch (ClassNotFoundException e){
            System.out.println(e);
        }catch (NotActiveException e){
            System.out.println(e);
        }

//        doer.findStudentByRollNo(30);

    }
}

```
something like this.

Basically, **The try block attempts to execute a risky code, and the catch block handles and manages any errors or exceptions that may occur during the execution of the try block.**

And at one time It handles only the single exception.

For example: 

**if in our above example ClassNotFoundException got caught then the NotActive Exception will not even be seen as the code execution will be out of the try-catch block.**

**[Note for Instructor:]** Explain the above line in detail.

To understand it further lets do an exercise: 

**[Ask from learners: ]**

What will be the output of the code if the given code throws a **NotActiveException Exception.**
```java
        try {
            System.out.println("Before find student by id");
            doer.findStudentByRollNumber(12);
            System.out.println("After find student by id");
            return;
        }  catch (ClassNotFoundException classNotFoundException) {
            System.out.println("Class was not found");
            throw classNotFoundException;
        } catch (NotActiveException notActiveException) {
            System.out.println("Student was not active");
        } catch (EvenNumberException evenNumberException) {
            System.out.println("Even number exception happened");
        } catch (Exception exception) {
            System.out.println("exception was thrown");
        }
```

**Ans :** Output: 
Before find student by id
Student was not active

- Basically the try-catch block start getting executed. First it pritned the "Before find student by id".
- Then it started to execute the function findStudentByRollNumber(),but it is throwing NotActiveExceptiona as given in the question.
- So the code will now handle it.
- It checks if its a ClassNotFoundExeption first. **No**.
- Then it checks if its a NotActiveException. **Yes**.
- So it will execute the function inside that catch.
- And we will be out of the try-catch block.

This is the complete process of how the **try-catch** block works.

Now lets understand about the **Finally keyword.**

### Finally Keyword.

The finally block, if present, contains code that will be executed regardless of whether an exception occurs or not in the try block.

it is a part of **handling exception.** 

Note:
- The **finally** may be present and may not be also.
- It will be executed regardless if the exception has occured or not.

For example here:

```java
try {
            System.out.println("Before find student by id");
            doer.findStudentByRollNumber(12);
            System.out.println("After find student by id");
            return;
        }  catch (ClassNotFoundException classNotFoundException) {
            System.out.println("Class was not found");
            throw classNotFoundException;
        } catch (NotActiveException notActiveException) {
            System.out.println("Student was not active");
        } catch (EvenNumberException evenNumberException) {
            System.out.println("Even number exception happened");
        } catch (Exception exception) {
            System.out.println("exception was thrown");
        } finally {
            System.out.println("I tried to call findStudentByRollNumber"); // must get executed
        }
```

**If it thorws the NotActiveException exception now. The output will be :**

Before find student by id
Student was not active
I tried to call findStudentByRollNumber

but what if findStudentByRollNumber() doesn't throws an excpetion then the output will be:


Before find student by id
**findStudentByRollNumber() gets executed.**
After find student by id
I tried to call findStudentByRollNumber

**So the finally keyword gives an assurity that the exception has been handled b executing the finally block.**

**[Note for instructor:]** Explain these two in deatil manner.

This marks the end of our Exception handling.