What is an Exception? An Exception is the term Java uses to refer to an error that has occurred during the course of your application's life-cycle. What do I mean by your application's life-cycle? The application life-cycle starts as soon as you hit the “Run as -> Java application” option. This is when your application kicks into life and the life-cycle starts.
When things go wrong during the course of your application's life-cycle, what's Java to do? Well, Java handles these issues by using something called Exception handling.
What do I mean by “issues”, well let's think of one example of an Exception – when you're trying to read through a File.
– Read a file that doesn't exist? FileNotFoundException
– Read a file that's locked? IOException
Another example -> Load way to many Objects into memory -> OutOfMemoryError
So when something goes wrong, what happens? Well, if you don't use any type of Exception handling, and you're running your application via the “Run As -> Java Application” then it will terminate with an error. The code flow simply stops and your application shuts down.
Well that sucks.
So how do we handle exceptions? Well, we use something called a try/catch block of code. Now as always, this is tough to do over a podcast, but I'll try to relate this code to something you're already familiar with. The try/catch block of code looks very similar to an if/else block of code with one exception (no pun intended): you know the part of the if statement that has the round brackets where you place your condition? Well, this goes on the catch part of the try/catch and it's not a condition you're placing in it, it's the type of exception you want to catch.
So, now that I've confused you, let me try to explain it again in another way. A try/catch block defines two separate blocks of code. The code in the try section, and the code in the catch section. These two sections are separated by curly braces (just like and if/else statement). I'll say it one more time before I move on, a try/catch block has two sections, two blocks of code – a try block and a catch block.
Okay, so what do these two sections do? Well, in the try block, you place all of the code that you would normally have written without the additional try/catch code. So just picture your regular old code in, let's say, the main method. Then instead of just having your regular old boring code written there, you can instead create a try block, and throw all of your code into it! What will this accomplish exactly? Well, what happens is this: if for any reason an exceptional circumstance arises anywhere in the code that's wrapped up all nice and cozy inside of your try block, then Java will move the execution of the code flow into the catch block that you've also defined.
So the important thing to notice here, is the difference between having a try/catch block and NOT having one. When you DON'T have a try/catch block, and an exception circumstance arises, Java will throw an exception, and since there's nothing there to catch it, the Exception will cause your whole application to terminate. BUT, if you happen to have a try block defined, and the exceptional circumstance arises inside of your try block, then Java won't throw the exception and terminate your application, instead it will throw the exception, which will then be caught by your catch block. Neat? I think so.
So then, while the code flows into the catch block, what are we supposed to do? Well, we're supposed to HANDLE the exceptional circumstance in some way. How do we “handle” it? That all depends on the type of exception that's thrown. For our purposes right now since we're just starting to learn about Exceptions, let's just say that all we need to do to handle the exception is to output the details of the exception to our console. So, boom, we log the exception to the console and what happens? We get a bunch of ugly red error messages appearing all over our console. So then, how is that any different from before right? We saw these same ugly red error messages before. Well, the difference is, now this time your whole application doesn't come to a grinding halt. The code will continue to execute outside of the catch block.
So, there's a lot of important stuff going on here. It all revolves around the concept of Java throwing and either catching or not catching Exceptions. When you don't have a try/catch block, you're not trying to catch an Exception, get it? If we don't try to catch, then we let the Exception do something called “propagate up the call stack”. I think in the next podcast I'll give you a rundown on what the call stack is and how it works. For now, just realize that if you don't try to catch, your application comes to a grinding halt if an exception is thrown.
So hopefully that concept is getting clearer to you. Now I want to talk about the flow of the code, because that's the second most important thing that's going on here. One question you may ask is, “Why don't I just wrap every line of my code with this try/catch block and call it a day?”. Well, great question, and it has everything to do with the flow of the code when you're dealing with exception handling. Side note: notice how the concept of a try/catch block is synonymous with the term exception handling? Well, that's because they are the same, in order to handle an exception you need a try/catch block.
As I mentioned before, the code will naturally flow into a try block of code just like it would if the try block wasn't even there. We're still going line by line from top to bottom here. So perhaps we're executing from top to bottom on some code that's not wrapped with a try block, but then we hit a try block, what happens? We just flow into the first line of code in the try block and continue like normal. If we go line by line down the code of the try block and NO exceptions occur (which is usually the majority of the time), then we'll exit the try block and completely skip the catch block. Remember, the catch block is only there to handle any exception that is thrown. So if nothing exceptional happens, then nothing is thrown, therefore we can ignore the code in the catch block. SO that's the normal flow of things, into a try block, execute every line, until the end of the try block, then we skip the catch block and continue on below the catch block like nothing happened.
The only way this flow is interrupted, is if on any given line of code inside the try block, Java throws an exception (again this could be because you're trying to read a file on some line of code inside your try block, and the file doesn't exist). What happens then is we SKIP every single line of code that remains in the try block and move into the catch block. We execute all the lines in the catch block (which in this case we'll say is just logging the error to the console), then come out of the catch block and resume the flow of code like everything's peachy.
This flow is hard to explain over audio, but I think the majority of you will be able to catch my drift here. So, back to my hypothetical question of “Why don't we just wrap every line of code with a try block and call it a day”. Well if we did that, then our code would behave EXACTLY like it did without the try/catch block. Because if an exception occurred, then Java would just skip ALL the rest of the lines of code in the application, and go to the catch block, output the error and the application would terminate. Not very helpful. So it's best to limit the scope of your try block to just the code that could throw an exception.
Okay, I think I've covered enough material on Exceptions for now, in the next podcast episode I'll talk a little bit more about exceptions, but I'll also talk about the call stack and what that has to do with exception handling. Before you listen to the next episode, I'll encourage you to head over to howtoprogramwithjava.com/session13 to SEE the actual exception handling code for yourself. I'll have a link at the end of the show notes that will point to your homework.
Before I end this episode, I want to say that I did not receive any emails from people asking any programming questions. So this means one of two things, either I've explained everything up to this point so well that no one has any questions (which I doubt), or you guys forgot to email in your questions for the podcast, so I'll say it again -> Send your programming questions into firstname.lastname@example.org, specify that you'd like to have the question answered on the podcast and don't forget to leave your first name so I can give you credit for the question. Oh and don't forget to leave a review for the show, I'll give the 5 star reviews a shout out at the top of the next show.
Take care and happy learning!
Read up on exceptions here: https://www.coderscampus.com/exceptions-in-java/