Exceptions:
- Short for exceptional event
- Disrupts the normal flow of events
- Is actually an object that is thrown after an errors occurs
- Thrown at runtime
- List of some Java exception classes:
- NullPointerException
- ArrayIndexOutOfBoundsException
- StringIndexOutOfBoundsException
- ArithmeticException
- ClassCastException
- IllegalArgumentException
Throwing an Exception:
- When an error occurs the throwFor() method is called
- It then creates an instance of the proper exception class
- Finally, it uses the throw operator to give the object to the JVM
The Call Stack:
General Information:
- Can be called either call stack trace or just stack trace
- The “stack” part of stack trace: Represents how method calls are internally managed by the JVM
- The “trace” part of stack trace: A list of method calls before the exception was thrown
- Read from bottom up
JVM Process
- JVM must store info about the state of the method it is running
- Saves value of a method’s local variables
- Saves a reference to the next instruction to execute once the JVM switches back to the method
- Once the called method is returned, the JVM retrieves the saved state of the calling method and continues
- Moves back up the method call hierarchy (Similar to how recursion works)
- Uses a stack-based data structure to store info
- The bottom of the stack is main and other method info are added to the top of the stack
- Once a method is complete, it is popped off of the stack
- When main is popped of the stack, the program ends
The Throwable Hierarchy:
- There is a hierarchy of exception types
- Throwable is at the top of the Hierarchy
- Sister classes Error and Exception are below
Error vs Exception Classes:
- Error subclasses are often errors that can’t be recovered from
- Ex. JVM no longer has any memory to run the program
- Exceptions give more flexibility in how they can be handled
Handling Exceptions by Catching:
- A way to catch an exception and run a block of code in response
- Allows for the separation of actual program code from error handling
- Makes code less confusing to read and write
- Done through a try-catch block
- Try: Attempts to run a block of code
- Catch: Catches the thrown exception and runs a block of code in response
- Has a parameter that represents the exception type
- Only runs if the exception matches the parameter exception type
- Multiple catch blocks can be used to catch multiple types of errors
- Can combine catch blocks together if their handling steps are the same
- Finally block:
- Can be added to the end of a try-catch block
- Always runs a block of code after try-catch
- Useful Instance methods of Throwable Objects:
- getMessage(): Returns details of exception
- printStackTrace(): Prints the stack trace of the exception
try {
//Code that attempts to run
} catch (ExceptionType identifier) {
//Code that runs if ExceptionType is thrown
} catch (ExceptionType2 identifier) {
//Code that runs if ExceptionType2 is thrown
} catch (ExceptionType3 || ExceptionType4) {
//Code that runs if ExceptionType3 or 4 is thrown
} finally {
//Code to run at the end of try-catch block
}
File I/O and the FileNotFoundException
WARNING
Check for null before calling any methods on an object
- The java.io.File class is used to interact with files in Java
- With the Scanner class, you can read the data of a file
- Will throw a FileNotFoundException if the Scanner attempts to read a non-existent file
- Every time an enter or return key is inserted into a text file, it inputs a newline character into the file
- This newline character determines where each line starts and ends in a file
- The java.io.PrintWriter class is used to print out data to a file
import java.io.File;
import java.io.PrintWriter;
import java.util.Scanner;
File fileIn = new File(inputFileName); //Creating a new File object to interact with the file
File fileOut = new File(outputFileName); //File object for output file
Scanner fileScan = new Scanner(fileIn); //Takes a File object as a parameter
PrintWriter filePrint = new PrintWriter(fileOut); //Takes a File object as a parameter
String line = fileScan.nextLine(); //Saving line of input file to a String
filePrint.println(line + "hi"); //Printing to output file
//Do null checks for both before closing
fileScan.close();
filePrint.close();
Declaring Exceptions to be Thrown (Removing try-catch requirement):
- Unlike ArrayIndexOutOfBoundsExceptions, Arithmetic and InputMismatch exceptions you can’t write code that might throw an exception without doing something in case it occurs
- Must either catch or declare the exception
- Declaring an exception doesn’t handle it
//Add throws followed by the exception name to declare an exception
public static void main(String[] args) throws ExceptionName {
}
Checked vs Unchecked Exceptions:
- Unchecked Exceptions: Exceptions that aren’t caught or declared
- This is done for very common exceptions that can happen in many different areas of our code
- It would be cumbersome and inefficient to catch/declare each one
- Ex. The RuntimeException class and its subclasses
- Checked Exceptions: Exceptions that must be caught or declared
- More uncommon than unchecked exceptions
- Ex. The IOException class and its subclasses
Defining an Exception and Using the Throw Operator:
- To write an exception, simply extend the exception class or any of its descendants
- Allows for the creation of more custom and specific exceptions
public class ExceptionName extends ParentExceptionName {
//Constructor
public ExceptionName {
//Code to run when the exception is triggered
}
}
- You can use an if-statement and the throw operator to throw an error based off a condition
if (conditon) {
throw new ExceptionName;
}
Delimited Files:
- Files that store structured data in a persistent manner
- CSVs (Comma Separated Values)
- We can use CSVs to store data that is persistent across multiple runs of a program using PrintWriter
- Must place commas in the correct locations between data
- The String.split() method can be used to split a String and store its values in an array
- You can use a regular expression to have multiple delimiters from which you can split from
String[] arrayName = stringName.split(delimiter); //Singular Delimiter
String[] arrayName = stringName.split("[A-Z]+"); //Example of using a regular expression (Will split from any capital letter)
- Scanners can also be used to parse delimited Strings
Scanner ScannerName = new Scanner(FileObject);
Scanner ScannerName2 = new Scanner(ScannerName.nextLine());
ScannerName2.useDelimiter(delimiter);
ScannerName2.nextInt(); //Example
ScannerName2.nextDouble(); //Example