At runtime if our java program violates JVM rules then JVM itself will creates and throws exception object. Here we don’t need throw statement to throw an exception.
Example 01: JVM create and throw exception if JVM rule violates
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.vidvaan.corejava.exception21.throwkeyword; //JVM throws exception when JVM rules violated public class Example01ThrowKeyword { public static void main(String[] args) { System.out.println("main begin"); int result = 1 / 0;// Here we are violating JVM rule // So here JVM creates and throws ArithmeticException System.out.println("main end"); } } |
Output :
main begin
Exception in thread “main” java.lang.ArithmeticException: / by zero
at com.vidvaan.corejava.exception21.throwkeyword.Example01ThrowKeyword.main(Example01ThrowKeyword.java:8)
In this example, Line :8 code violates one of the JVM rule(division by zero), So JVM itself creates and throws ArithmeticException object. Here we are not using ‘throw’ keyword to throw exception.
For every JVM rule violation, JVM has defined specific exception to throw. For Example, if you try to perform operation on null then it will throw NullPointerException, If you try to divide with zero it will throw ArithmeticException. Like wise for every violation JVM throws specific exception.
Example 02: JVM doesn’t create and throw exception for business rules violation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package com.vidvaan.corejava.exception21.throwkeyword; //JVM doesn't create and throw exception for business rules violation public class Example02ThrowKeyword { public static void main(String[] args) { BankAccount obj = new BankAccount(); System.out.println("Before withdraw Balance : " + obj.balanceEnquiry()); obj.withDrawAmount(2000); System.out.println("After withdraw Balance : " + obj.balanceEnquiry()); } } class BankAccount { private int accountBalance = 1000; public void withDrawAmount(int withDrawalAmount) { // Here we are violating business rule if withDrawalAmount > accountBalance accountBalance = accountBalance - withDrawalAmount; } public void depositAmount(int depositAmount) { accountBalance = accountBalance + depositAmount; } public int balanceEnquiry() { return accountBalance; } } |
Output :
Before withdraw Balance : 1000
After withdraw Balance : -1000
In this example, At Line :17 we declared int accountBalance = 1000; Here int data type does allows even negative values also. That is the reason why at Line:21 even when we try to deduct more amount than available balance JVM didn’t throw exception. Because this is not JVM rule violation.
Here exactly we need to create and throw exception explicitly. Here we could make use of ‘throw‘ keyword to throw exception.
throw keyword
The Java throw keyword is used to explicitly throw an exception.
We can throw either checked or uncheked exception by throw keyword.
The throw keyword can be used to throw predefined exception or custom exception(user defined exception).
So throw keyword used to terminate the execution of block or method or application when our business rules are violated in application.
The syntax of java throw keyword is given below.
1 |
throw exception_object_reference; |
Let’s see the example of throw IllegalArgumentException.
1 2 |
IllegalArgumentException exception = new IllegalArgumentException("argument is invalid"); throw exception ; |
If you don’t need reference of exception object then we can throw as follows.
1 |
throw new IllegalArgumentException("argument is invalid"); |
Example 03: Create and throw predefined exception when business rule violated
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package com.vidvaan.corejava.exception21.throwkeyword; // We create and throw predefined exception when business rule violated public class Example03ThrowKeyword { public static void main(String[] args) { BankAccount2 obj = new BankAccount2(); System.out.println("Before withdraw Balance : " + obj.balanceEnquiry()); obj.withDrawAmount(2000); System.out.println("After withdraw Balance : " + obj.balanceEnquiry()); } } class BankAccount2 { private int accountBalance = 1000; public void withDrawAmount(int withDrawalAmount) { // Here explicitly throwing predefined exception when business rule violated if (withDrawalAmount > accountBalance) { throw new IllegalArgumentException("Insufficient Funds!!!"); } accountBalance = accountBalance - withDrawalAmount; } public void depositAmount(int depositAmount) { accountBalance = accountBalance + depositAmount; } public int balanceEnquiry() { return accountBalance; } } |
Output :
Before withdraw Balance : 1000
Exception in thread “main” java.lang.IllegalArgumentException: Insufficient Funds!!!
at com.vidvaan.corejava.exception21.throwkeyword.BankAccount2.withDrawAmount(Example03ThrowKeyword.java:22)
at com.vidvaan.corejava.exception21.throwkeyword.Example03ThrowKeyword.main(Example03ThrowKeyword.java:9)
In the above example, At Line :22 if withDrawalAmount > accountBalance then we are creating and throwing IllegalArgumentException. So the program got terminated.
Good thing here is we are not allowing the withdrawal when there are no sufficient funds in the account.
Bad thing here is the complete program has terminated which is not acceptable. If certain block or method is violating business rules then we need to terminate only that particular block or method but not the whole application.
So we will rewrite above example to terminate certain code when business rule violated instead terminating whole application.
Example 04: Termination limiting to certain block of code when exception raised
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
package com.vidvaan.corejava.exception21.throwkeyword; //We create and throw predefined exception when business rule violated //termination limiting to certain block of code public class Example04ThrowKeyword { public static void main(String[] args) { BankAccount3 obj = new BankAccount3(); System.out.println("Before withdraw Balance : " + obj.balanceEnquiry()); // limit termination of execution to withDrawAmount() method instead whole app try { obj.withDrawAmount(2000); } catch (IllegalArgumentException e) { System.out.println("Withdraw Failed : " + e.getMessage()); } System.out.println("After withdraw Balance : " + obj.balanceEnquiry()); } } class BankAccount3 { private int accountBalance = 1000; public void withDrawAmount(int withDrawalAmount) { // Here explicitly throwing predefined exception when business rule violated if (withDrawalAmount > accountBalance) { throw new IllegalArgumentException("Insufficient Funds!!!"); } accountBalance = accountBalance - withDrawalAmount; } public void depositAmount(int depositAmount) { accountBalance = accountBalance + depositAmount; } public int balanceEnquiry() { return accountBalance; } } |
Output :
Before withdraw Balance : 1000
Withdraw Failed : Insufficient Funds!!!
After withdraw Balance : 1000
In the above example, we can see that as business rule is violated not whole application is terminated only certain part of application terminated. This is the better way of handling exception.
Example 05: Create and throw user defined exception when business rule violated
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
package com.vidvaan.corejava.exception21.throwkeyword; //We create and throw user defined exception when business rule violated public class Example05ThrowKeyword { public static void main(String[] args) { BankAccount4 obj = new BankAccount4(); System.out.println("Before withdraw Balance : " + obj.balanceEnquiry()); // limit termination of execution to withDrawAmount() method instead whole app try { obj.withDrawAmount(2000); } catch (InsufficientFundsException e) { System.out.println("Withdraw Failed : " + e.getMessage()); } System.out.println("After withdraw Balance : " + obj.balanceEnquiry()); } } class BankAccount4 { private int accountBalance = 1000; public void withDrawAmount(int withDrawalAmount) { // Here explicitly throwing predefined exception when business rule violated if (withDrawalAmount > accountBalance) { throw new InsufficientFundsException("Insufficient Funds!!!"); } accountBalance = accountBalance - withDrawalAmount; } public void depositAmount(int depositAmount) { accountBalance = accountBalance + depositAmount; } public int balanceEnquiry() { return accountBalance; } } // User defined exception for specific business rule violation class InsufficientFundsException extends RuntimeException { public InsufficientFundsException(String message) { super(message); } } |
Output :
Before withdraw Balance : 1000
Withdraw Failed : Insufficient Funds!!!
After withdraw Balance : 1000
In the above example, we defined user defined exception called ‘InsufficientFundsException’ to specify specific business rule violation. It is always recommended to define custom exception for every business rule violation instead of using predefined exceptions.
Example 06: throw ‘null’ leads to NullPointerException
1 2 3 4 5 6 7 8 9 10 11 |
package com.vidvaan.corejava.exception21.throwkeyword; //throw 'null' leads to NullPointerException public class Example06ThrowKeyword { public static void main(String[] args) { IllegalArgumentException exception = null; throw exception; } } |
Output :
Exception in thread “main” java.lang.NullPointerException: Cannot throw exception because “exception” is null
at com.vidvaan.corejava.exception21.throwkeyword.Example06ThrowKeyword.main(Example06ThrowKeyword.java:8)
Example 07: Statements immediately after ‘throw’ causes Compilation error
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.vidvaan.corejava.exception21.throwkeyword; //statements immediately after 'throw' causes Compilation error. public class Example07ThrowKeyword { public static void main(String[] args) { System.out.println("main begin"); throw new IllegalArgumentException("somthing not correct"); // System.out.println("main end");// Compilation Error : Unreachable code } } |
Unconditional throw statement should be the last statement in the block or method.
Example 08: Statements after ‘throw’ is allowed if ‘throw’ is conditional
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.vidvaan.corejava.exception21.throwkeyword; //statements immediately after 'throw' causes Compilation error. public class Example08ThrowKeyword { public static void main(String[] args) { System.out.println("main begin"); if (true) { throw new IllegalArgumentException("somthing not correct"); } System.out.println("main end");// No Compilation Error } } |
Example 09: Throwing non Throwable types leads to Compilation error
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.vidvaan.corejava.exception21.throwkeyword; //throwing non Throwable types leads to Compilation error public class Example09ThrowKeyword { public static void main(String[] args) { // throw new String("somthing not correct"); // Compilation Error : No exception of type String can be thrown; an exception // type must be a subclass of Throwable } } |
In the above example we are trying to throw ‘String’ class object. But we should throw of type ‘Throwable’ or its subclass. Otherwise it leads to compilation error.
Example 10: Throwing checked exception leads to Compilation error
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package com.vidvaan.corejava.exception21.throwkeyword; import java.io.IOException; //throw checked exception public class Example10ThrowKeyword { public static void main(String[] args) { System.out.println("main begin"); doStuff(); System.out.println("main end"); } public static void doStuff() { // Compilation Error : Unhandled exception type IOException throw new IOException("somthing not correct"); } } |
In the above example, we are throwing checked exception in doStuff() method. If a code throws unchecked exception, the compiler demand us to handle or declare exception. Otherwise we will get compilation error. Here explained how to handle checked exceptions.