And in today's lesson, we're going to learn about exceptions. What are exceptions? Well, they're exceptional events. It's an event that occurs during the execution of a program. And what it does is it disrupts the normal flow of the program instructions. And when this error occurs inside of a method, the method creates an object, and hands it off to the runtime system. That object, which is called an exception object, contains information about the error, including the type and the state of the program when the error occurred. creating an exception object and handling it to the runtime system, is known as throwing the exception. In the old days, the program would produce a system dump of its memory. Now after a method throws an exception, the runtime system tries to find something to handle it. The set of possible somethings to handle the exception, is the ordered list of methods that have been called, to get the method where the error occurred. Why do we use exceptions? Well, what we wanna do is separate the error handling code from the regular code. Exceptions allow us to separate the details of what to do when something out of the ordinary happens, and we separate that from the main logic of a program. It makes our code much easier to read. Types of exceptions include, what happens if the file we're trying to open, can't be opened? What happens if the length of a file can't be determined? What happens if there's not enough memory to be allocated? What happens if a read fails? What happens if the file can't be closed? Without exceptions, we'd have to mix the error handling code with the code that actually performs the logic of the program. So we open the file, if the file opens, we then determine the length of the file. If the file length is good, then we allocate that much memory. If we have enough memory, then we read the file. As you can see, there is so much error detection inside the code, that the code becomes long, and difficult to follow, with a series of nested if statements. When there's that much error checking inside the code, we lose track of the logical flow of the code, and it makes it hard to debug, and understand exactly what the code is doing. We can group and differentiate error types, and because all exceptions thrown within a program are objects, the grouping becomes easy, and it's a natural outcome of the class hierarchy that Java has built upon. A method can catch an exception based on its group, or general type, by specifying any of the exceptions super classes in the catch statement. And we'll look at try catch statement next. But exception handlers should be as specific as possible. Determine the type of exception, before deciding on the best recovery strategy. By not catching specific errors, handlers must accommodate any possibility. And if we have exception handlers that are too general, that can make the code more error prone, by catching and handling exceptions that weren't anticipated by the programmer, and for that the handler was not intended. An exception is some sort of an event. It occurs during the running of the program, and it stops the normal flow of the program. When the error occurs, the method creates an object, and hands it off to the runtime system. There's a lot of things that go on behind the scenes, but we can handle these exceptions, and produce some output that explain what happens. Now, there are a bunch of different possible exceptions, and we can handle every single one of them, and what we're going to see, is how to handle the exception that we know might happen. Exceptions can separate the details of what to do when something out of the ordinary happens, and it keeps it apart from the main logic of the program. And because all of these exceptions are objects, we can group or categorize them, so that they make sense. When we write these exceptions, we want to be as specific as possible. And let's take a look exactly what I'm talking about. I'll scroll down, and here's our program. It's a simple program, I create an integer, called divide by zero, and I set it equal to zero. Then I have a try catch block, starting in line 45. The idea here is that before I divide by zero, it's going to test to see if the division will work. If there's an arithmetic exception, it will print out the arithmetic exception, and a message of what I was trying to do. And then a finally block that says, this is going to happen no matter what. Let's run this program, and see what happens. Now the first time I've run it, I have it working perfectly, because my divide by zero is five divided by one. What happens is if I change the one to a zero, and I try to divide by zero, this is the line of code that's going to generate the exception. The program's going to try to do the division. When the exception happens, it catches that arithmetic exception, and then prints out the message. Let's run it and see what happens. We tried to divide by zero, five divided by zero. The program caught our error and said, the arithmetic exception by zero is the problem. And finally, the block of code always gets executed, and the divide by zero variable was not changed. What's important to know here, is that the program completed successfully, and the printout is the thing that needs to be reviewed to see what might have gone wrong. Now you know how exceptions can be handled before they cause a problem in your program.