Where to use try-catch in java?
We know that java has an Exception handling feature, to handle the exception in the code instead of throwing them we can use try-catch in the code.
First, we will see how we can throw exceptions instead of handling using try-catch from one method to another. As shown in the following program we are using the throws keyword at the method level from readFile and main method. If a file is not present, an exception will be thrown and shown.
class Test {
public static void main(String args[]) throws FileNotFoundException {
MyClass myClass = new MyClass();
myClass.readFile(“abx.txt”);
}
}
class MyClass {
public void readFile(String filename) throws FileNotFoundException {
FileReader reader = new FileReader(new File(filename));
}
}
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:216)
at java.base/java.io.FileInputStream.
at java.base/java.io.FileReader.
at MyClass.readFile(Test.java:12)
at Test.main(Test.java:6)
We can use try-catch in the main method or readFile method instead of throwing FileNotFoundException as shown in the following program.
class Test {
public static void main(String args[]){
MyClass myClass = new MyClass();
try {
myClass.readFile(“abx.txt”)
}catch(FileNotFoundException e) {
System.out.println(“Specified file not found”);
}
}
}
class MyClass {
public void readFile(String filename) throws FileNotFoundException {
FileReader reader = new FileReader(new File(filename));
}
}
Java try-catch-finally:
If we want to run any particular code irrespective of the exception that occurred in the code or not, we can include that code in the ‘finally’ block.
In the following program for both without exception and with Exception case ‘finally’ block is executed.
public static void main(String args[]) {
MyClass myClass = new MyClass();
System.out.println(“———- With non-zero divider ———-“);
myClass.getDivision(8, 4);
System.out.println(“———- With zero divider ———-“);
myClass.getDivision(8, 0);
}
}
class MyClass {
public void getDivision(int a, int b) {
try {
int c = a / b;
System.out.println(“Division for ” + a + “/” + b + ” is: ” + c);
} catch (ArithmeticException e) {
System.out.println(“Can not divide by zero”);
} finally {
System.out.println(“Inside Finally block”);
}
}
}
Division for 8/4 is: 2
Inside Finally block
———- With zero divider ———-
Can not divide by zero
Inside Finally block
Multiple catch blocks:
We can include multiple catch blocks if we want to treat different types of exceptions with different codes.
For example, if we want to convert any string into an integer then we will get the NumberFormatException, and if we try to divide by zero we get ArithmeticException, and we can catch these 2 exceptions in different catch blocks.
public static void main(String args[]) {
MyClass myClass = new MyClass();
System.out.println(“———- With non-integer value ———-“);
myClass.getDivision(“8”, “a”);
System.out.println(“———- With zero divider ———-“);
myClass.getDivision(“8”, “0”);
}
}
class MyClass {
public void getDivision(String a, String b) {
try {
int c = Integer.parseInt(a) / Integer.parseInt(b);
System.out.println(“Division for ” + a + “/” + b + ” is: ” + c);
} catch (NumberFormatException e) {
System.out.println(“NumberFormatException: Not proper data for number value”);
} catch (ArithmeticException e) {
System.out.println(“ArithmeticException: Can not divide by zero”);
}
}
}
NumberFormatException: Not proper data for number value
———- With zero divider ———-
ArithmeticException: Can not divide by zero
Exceptions in multiple catch blocks must follow an order if there is a parent-child relationship between the two exceptions. If we catch the parent exception first and then try to catch the child exception then we will get a compile-time error as shown in the following example. NumberFormatException is a child of RuntimeException. If we catch RuntimeException first and then NumberFormatException we will get a compile-time error.
public static void main(String args[]) {
MyClass myClass = new MyClass();
System.out.println(“———- With non-integer value ———-“);
myClass.getDivision(“8”, “a”);
System.out.println(“———- With zero divider ———-“);
myClass.getDivision(“8”, “0”);
}
}
class MyClass {
public void getDivision(String a, String b) {
try {
int c = Integer.parseInt(a) / Integer.parseInt(b);
System.out.println(“Division for ” + a + “/” + b + ” is: ” + c);
} catch (RuntimeException e) {
System.out.println(“RuntimeException Occured: Message: ” + e.getMessage());
} catch (NumberFormatException e) {
System.out.println(“NumberFormatException: Not proper data for number value”);
}
}
}
} catch (NumberFormatException e) {
If we change the order for catch blocks in the above code compile-time error will be resolved and we will get the following
Catch block with multiple exceptions.
We can include multiple exceptions in one catch block by ‘|’ as shown in the following program. If we want to handle different errors in a common catch block then we can include all the exceptions in catch separated by |.
public static void main(String args[]) {
MyClass myClass = new MyClass();
System.out.println(“———- With non-integer value ———-“);
myClass.getDivision(“8”, “a”);
System.out.println(“———- With zero divider ———-“);
myClass.getDivision(“8”, “0”);
}
}
class MyClass {
public void getDivision(String a, String b) {
try {
int c = Integer.parseInt(a) / Integer.parseInt(b);
System.out.println(“Division for ” + a + “/” + b + ” is: ” + c);
} catch (NumberFormatException | ArithmeticException e) {
System.out.println(“Exception occurred, message: ” + e.getMessage());
}
}
}
Exception occurred, message: For input string: “a”
———- With zero divider ———-
Exception occurred, message: / by zero