Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Analogy for Java try catch block –
Java try block is used to enclose the code that might throw an exception. It must be used within the method. Java try block must be followed by either catch or finally block.
Thinking with anology: Think of the Java try block as a safety net that catches any errors (exceptions) that might occur in your code, like a safety net catching acrobats in a circus performance.
Checked Exception aka Compile time enforced Exception –
Unchecked Exception aka Runtime Exception –
FAQs:
When do you use a Checked exception over Unchecked exception ?
If you want to enforce the developer to handle an exception you declare the exception as a checked exception so compiler will ensure that developer has handled the exception.
Because, If an exception is a checked exception, it means that it need to be declared in method signatures.
Your library Exception hierarchy can look like –
root exception class for a type e.g. UserException – The root class for all defined user exceptions.
protected constructor() – This constructor can only be called by subclasses.
Exception class hierarchy:
Exception <- Throwable <- Object
Exception is a Throwable.
Methods inherited from class java.lang.Throwable which is a superclass for Exception:
addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
Why we would want FileNotFoundException to be a checked –
“Stuff that goes wrong” comes in two basic flavours: recoverable, and unrecoverable… Ergo: Business Exceptions and System Errors.
Two types of developers:
IOException is a “catch all” checked exception. why ?
Philosopy on why Java has both checked and unchecked exception:
https://stackoverflow.com/questions/1074358/why-does-java-have-both-checked-and-unchecked-exceptions
When an exception happens –
un-intentionally bubbling up should be fixed in your code because –
Understanding checked exception with anology:
When designing an interface, think of exceptional cases that can occur, and will occur, with the normal state of a method call. Declare these exceptions in your interface, as the programmer will have to handle them directly.
For example, a bank account withdraw method may declare an OverdraftException, which is an expected exception – a withdrawal may fail due to overdraft, but this type of failure may be handled differently by the client code (one may decide to completely deny the withdrawal, another may decide to apply a huge penalty and allow for a negative balance to be recorded, another may decide that their client is allowed to draw from a different account).
In case of run-time exceptions –
Developer can choose to handle it or developer can choose to let it propagate and be logged as an error. Default is: propagates and so not noob friendly to handle expceptions but a pain in ass for experts as all they want is to let is propagate and don’t want to write boiler plate code to let it propagate.
generally you cannot do anything but log that an error occur
Have a root exception for a class of exception and child/subclass exceptions with Exception names that should clearly show what happened when they are called.
e.g.
UserException -> ObjectNotFoundException -> DomainNotFoundException
SystemExcepiton -> OOMError
UserException in this case is a defined Root Exception
DomainNotFoundException clearly says we couldn’t find Domain which is a object not found and more clearly a user exception as the user called with a exception that doesn’t exist.
SQLException is a bad checked exception. Exception names should show what happened when they are called. SQLException does not. SQLException is thrown any single time any possible number of errors are encountered when dealing with a database – MOST OF WHICH THAT HAVE NOTHING TO DO WITH SQL.
Pros of checked exceptions –
Cons of checked exceptions –
Pros of unchecked/run-time exceptions –
Cons of unchecked/run-time exceptions –
Spring uses a DataAccessException to wrap SQLExceptions so that you don’t have to handle them as a checked exception.
SQLException which is a checked exception eats a lot of exceptions –
So Spring wrap of SQL Exception as DataAccessException is more preferrable because all true SQL exceptions would be caught during development and testing (unless runtime query building with bad SQL query) and in production it is highly likely an issue to access the data from database like say caused by database connection/database health/network to database issue i.e. not that your SQL query was nessecarily at fault.
Final Takeaways:
Why SQLException should have been unchecked exception:
IOException is a superclass for even Network related exception and making it a checked exception could have made Server handle retries. In this case it should been shamelessly propagated and passed to client and client can determine what to do – retry / fallback to another provider etc. Bubbiling up several runtime exceptions into one generic IOException is a nonsense for developers as it is difficult to figure out how to handle it.
Case Study:
FileNotFoundException is a checked exception even though it happens at runtime and in most cases there is no recovery possible. Shouldn’t it be a unchecked exception ?
Why your reasoning makes sense:
Runtime Occurrence: You’re correct that whether a file exists or not can only be definitively determined at runtime. The compiler can’t predict if every possible file path you provide in your code will be valid when the program executes.
Spirit of Unchecked Exceptions: Unchecked exceptions are generally reserved for issues that are often results of programming errors (e.g., NullPointerException, IndexOutOfBoundsException). Since a missing file could be due to external factors outside the program’s control, FileNotFoundException seems to fit better in the “unchecked” category.
Arguments for keeping FileNotFoundException checked:
Enforced Error Handling: Checked exceptions force developers to explicitly consider and handle potential file access problems. This encourages a more robust approach to file I/O and can help avoid unexpected crashes in production environments.
Recoverability: In many cases, a FileNotFoundException is recoverable. The user might be asked to provide a different file path, or the program could implement a default behavior if the file is optional. Checked exceptions promote this kind of structured error handling.
Legacy and Consistency: Changing FileNotFoundException to unchecked now would have ripple effects throughout the Java ecosystem, breaking existing code that relies on the current behavior. Java tends to be conservative in making such fundamental changes.
Could it be different?
Absolutely! Some programming languages handle file-related errors with unchecked exceptions. There’s a degree of design philosophy involved in this decision. Java prioritizes the benefits listed above, even if it means slightly more verbose code.
Example (how to handle it):
Java
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class FileReadingExample {
public static void main(String[] args) {
File file = new File("my_file.txt");
try {
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
scanner.close();
} catch (FileNotFoundException e) {
System.err.println("Error: File not found. Please check the path.");
}
}
}
Scenario 1: FileNotFoundException (Checked)
Detailed Example
Java
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class FileReader {
public static void main(String[] args) {
String filename = "my_data.txt";
try {
readFile(filename);
} catch (FileNotFoundException e) {
System.err.println("Error: File not found - " + filename);
// Add code to recover: ask the user for a new filename, etc.
}
}
public static void readFile(String filename) throws FileNotFoundException {
File file = new File(filename);
Scanner scanner = new Scanner(file);
// ... Process the file contents ...
scanner.close();
}
}
Scenario 2: NullPointerException (Unchecked)
Detailed Example
Java
public class MyClass {
private String message; // Not initialized
public void printMessage() {
System.out.println(message.length()); // Uh oh! 'message' is null
}
}
Scenario 3: ArrayIndexOutOfBoundsException (Unchecked)
Detailed Example
Java
public class ArrayExample {
public static void main(String[] args) {
int[] numbers = {10, 20, 30};
System.out.println(numbers[3]); // Array only has elements 0, 1, and 2
}
}
Sources: