UNIT III Notes
UNIT III Notes
What is an exception?
An Exception is an unwanted event that interrupts the normal flow of the program.
When an exception occurs program execution gets terminated. In such cases we get a
system generated error message.
The good thing about exceptions is that java developer can handle these exception in
such a way so that the program doesn’t get terminated abruptly and the user get a
meaningful error message.
For example: You are writing a program for division and both the numbers are
entered by user. In the following example, user can enter any number, if user enters
the second number (divisor) as 0 then the program will terminate and throw an
exception because dividing a number by zero gives undefined result. To get the user
input, we are using Scanner class. Notice the output of the program.
Note: Do not worry about the try and catch blocks as we have covered these topics in
detail in separate tutorials. For now just remember that the code that can throw
exception needs to be inside try block and the catch block follows the try block, where
the exception error message is set.
}}
Output:
If an exception occurs, which has not been handled by programmer then program
execution gets terminated and a system generated error message is shown to the user.
These system generated messages are not user friendly so a user will not be able to
understand what went wrong. In order to let them know the reason in simple
language, we handle exceptions. We handle such exceptions and then prints a user
friendly warning message to user, which lets them correct the error as most of the
time exception occurs due to bad data provided by user.
Exceptions are events that occurs during runtime due to bad data entered by user or
an error in programming logic. A programmer can handle such conditions and take
necessary corrective actions. Few examples:
NullPointerException – When you try to use a reference that points to null.
ArithmeticException – When bad data is provided by user, for example, when you try
to divide a number by zero this exception occurs because dividing a number by zero is
undefined.
ArrayIndexOutOfBoundsException – When you try to access the elements of an array
out of its bounds, for example array size is 5 (which means it has five elements) and
you are trying to access the 10th element.
Types of exceptions
There are two types of exceptions in Java:
1) Checked exceptions
2) Unchecked exceptions
I have covered these topics in detail in a separate tutorial: Checked and Unchecked
exceptions in Java.
1) Checked exceptions
All exceptions other than Runtime Exceptions are known as Checked exceptions as
the compiler checks them during compilation to see whether the programmer has
handled them or not. If these exceptions are not handled/declared in the program, you
will get compilation error. For example, SQLException, IOException,
ClassNotFoundException etc.
2) Unchecked Exceptions
Runtime Exceptions are also known as Unchecked Exceptions. These exceptions are
not checked at compile-time so compiler does not check whether the programmer has
handled them or not but it’s the responsibility of the programmer to handle these
exceptions and provide a safe exit.
catch: The catch block is where we write the logic to handle the exception, if it
occurs. A catch block only executes if an exception is caught by the try block. A catch
block is always accompanied by a try block.
throws: It is used in method signature. It indicates that this method might throw one
of the declared exceptions. While calling such methods, we need to handle the
exceptions using try-catch block.
Note: A try block must be followed by catch blocks or finally block or both.
try{
//statements that may cause an exception}catch(Exception e){
//statements that will execute when exception occurs}
Syntax of try block with finally block
try{
//statements that may cause an exception}finally{
//statements that execute whether the exception occurs or not}
Syntax of try-catch-finally in Java
try{
//statements that may cause an exception}catch(Exception e){
//statements that will execute if exception occurs}finally{
//statements that execute whether the exception occurs or not}
Note: It is upto the programmer to choose which statements needs to be placed inside
try block. If programmer thinks that certain statements in a program can throw a
exception, such statements can be enclosed inside try block and potential exceptions
can be handled in catch blocks.
You can catch different exceptions in different catch blocks. When an exception
occurs in try block, the corresponding catch block that handles that particular
exception executes. For example if an arithmetic exception occurs in try block then
the statements enclosed in catch block for arithmetic exception executes.
try{
//statements that may cause an exception}catch (exception(type) e(object)){
//error handling code}
Example: try catch in Java
If an exception occurs in try block then the control of execution is passed to the
corresponding catch block. As discussed earlier, a single try block can have multiple
catch blocks associated with it, you should place the catch blocks in such a way that
the generic exception handler catch block is at the last(see in the example below).
The generic exception handler can handle all the exceptions but you should place is
at the end, if you place it at the before all the catch blocks then it will display the
generic message. You always want to give the user a meaningful message for each
type of exception rather then a generic message.
class Example1 {
public static void main(String args[]) {
int num1, num2;
try {
/* We suspect that this block of statement can throw
* exception so we handled it by placing these statements
* inside try and handled the exception in catch block
*/
num1 = 0;
num2 = 62 / num1;
System.out.println(num2);
System.out.println("Hey I'm at the end of try block");
}
catch (ArithmeticException e) {
/* This block will only execute if any Arithmetic exception
* occurs in try block
*/
System.out.println("You should not divide a number by zero");
}
catch (Exception e) {
/* This is a generic Exception handler which means it can handle
* all the exceptions. This will execute if the exception is not
* handled by previous catch blocks.
*/
System.out.println("Exception occurred");
}
System.out.println("I'm out of try-catch block in Java.");
}}
Output:
1. As I mentioned above, a single try block can have any number of catch blocks.
catch(Exception e){
//This catch block catches all the exceptions}
If you are wondering why we need other catch handlers when we have
a generic that can handle all. This is because in generic exception
handler you can display a message but you are not sure for which type
of exception it may trigger so it will display the same message for all
the exceptions and user may not be able to understand which exception
occurred. Thats the reason you should place is at the end of all the
specific exception catch blocks
3. If no exception occurs in try block then the catch blocks are completely ignored.
class Example2{
public static void main(String args[]){
try{
int a[]=new int[7];
a[4]=30/0;
System.out.println("First print statement in try block");
}
catch(ArithmeticException e){
System.out.println("Warning: ArithmeticException");
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("Warning: ArrayIndexOutOfBoundsException");
}
catch(Exception e){
System.out.println("Warning: Some Other exception");
}
System.out.println("Out of try-catch block...");
}}
Output:
try {
// Code that may throw an exception
} catch (ExceptionType1 e1) {
// Handle exception of type ExceptionType1
} catch (ExceptionType2 e2) {
// Handle exception of type ExceptionType2
} finally {
// Code that will always execute
class Example{
public static void main(String args[]){
try{
int arr[]=new int[7];
arr[4]=30/0;
System.out.println("Last Statement of try block");
}
catch(ArithmeticException e){
System.out.println("You should not divide a number by zero");
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("Accessing array elements outside of the limit");
}
catch(Exception e){
System.out.println("Some Other Exception");
}
System.out.println("Out of the try-catch block");
}}
Output:
Now lets change the code a little bit and see the change in output:
class Example{
public static void main(String args[]){
try{
int arr[]=new int[7];
arr[10]=10/5;
System.out.println("Last Statement of try block");
}
catch(ArithmeticException e){
System.out.println("You should not divide a number by zero");
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("Accessing array elements outside of the limit");
}
catch(Exception e){
System.out.println("Some Other Exception");
}
System.out.println("Out of the try-catch block");
}}
Output:
class Example{
public static void main(String args[]){
try{
int arr[]=new int[7];
arr[10]=10/5;
System.out.println("Last Statement of try block");
}
catch(Exception e){
System.out.println("Some Other Exception");
}
catch(ArithmeticException e){
System.out.println("You should not divide a number by zero");
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("Accessing array elements outside of the limit");
}
System.out.println("Out of the try-catch block");
}}
Output:
If neither catch block nor parent catch block handles exception then the system
generated message would be shown for the exception, similar to what we see when
we don’t handle exception.
Lets see the syntax first then we will discuss this with an example.
This is how the structure is: try-block3 is inside try-block2 and try-block2 is inside
main try-block, you can say that the main try-block is a grand parent of the try-
block3. Refer the explanation which is given at the end of this code.
class NestingDemo{
public static void main(String args[]){
//main try-block
try{
//try-block2
try{
//try-block3
try{
int arr[]= {1,2,3,4};
/* I'm trying to display the value of
* an element which doesn't exist. The
* code should throw an exception
*/
System.out.println(arr[10]);
}catch(ArithmeticException e){
System.out.print("Arithmetic Exception");
System.out.println(" handled in try-block3");
}
}
catch(ArithmeticException e){
System.out.print("Arithmetic Exception");
System.out.println(" handled in try-block2");
}
}
catch(ArithmeticException e3){
System.out.print("Arithmetic Exception");
System.out.println(" handled in main try-block");
}
catch(ArrayIndexOutOfBoundsException e4){
System.out.print("ArrayIndexOutOfBoundsException");
System.out.println(" handled in main try-block");
}
catch(Exception e5){
System.out.print("Exception");
System.out.println(" handled in main try-block");
}
}}
Output:
ArrayIndexOutOfBoundsException handled in main try-block
As you can see that the ArrayIndexOutOfBoundsException occurred in the grand
child try-block3. Since try-block3 is not handling this exception, the control then gets
transferred to the parent try-block2 and looked for the catch handlers in try-block2.
Since the try-block2 is also not handling that exception, the control gets transferred to
the main (grand parent) try-block where it found the appropriate catch block for
exception. This is how the the nesting structure works.
class Nest{
public static void main(String args[]){
//Parent try block
try{
//Child try block1
try{
System.out.println("Inside block1");
int b =45/0;
System.out.println(b);
}
catch(ArithmeticException e1){
System.out.println("Exception: e1");
}
//Child try block2
try{
System.out.println("Inside block2");
int b =45/0;
System.out.println(b);
}
catch(ArrayIndexOutOfBoundsException e2){
System.out.println("Exception: e2");
}
System.out.println("Just other statement");
}
catch(ArithmeticException e3){
System.out.println("Arithmetic Exception");
System.out.println("Inside parent try catch block");
}
catch(ArrayIndexOutOfBoundsException e4){
System.out.println("ArrayIndexOutOfBoundsException");
System.out.println("Inside parent try catch block");
}
catch(Exception e5){
System.out.println("Exception");
System.out.println("Inside parent try catch block");
}
System.out.println("Next statement..");
}}
Output:
Inside block1Exception: e1Inside block2Arithmetic ExceptionInside parent try catch
blockNext statement..
This is another example that shows how the nested try block works. You can see that
there are two try-catch block inside main try block’s body. I’ve marked them as block
1 and block 2 in above example.
Block1: I have divided an integer by zero and it caused an ArithmeticException,
since the catch of block1 is handling ArithmeticException "Exception: e1" displayed.
Parent try Catch block: No exception occurred here so the “Next statement..”
displayed.
The important point to note here is that whenever the child catch blocks are not
handling any exception, the jumps to the parent catch blocks, if the exception is not
handled there as well then the program will terminate abruptly showing system
generated message.
try {
//Statements that may cause an exception}catch {
//Handling exception}finally {
//Statements to be executed}
A Simple Example of finally block
Here you can see that the exception occurred in try block which has been handled in
catch block, after that finally block got executed.
class Example{
public static void main(String args[]) {
try{
int num=121/0;
System.out.println(num);
}
catch(ArithmeticException e){
System.out.println("Number should not be divided by zero");
}
/* Finally block will always execute
* even if there is no exception in try block
*/
finally{
System.out.println("This is finally block");
}
System.out.println("Out of try-catch-finally");
} }
Output:
3. In normal case when there is no exception in try block then the finally block is
executed after try block. However if an exception occurs then the catch block is
executed before finally block.
4. An exception in the finally block, behaves exactly like any other exception.
5. The statements present in the finally block execute even if the try block contains
control transfer statements like return, break or continue.
Lets see an example to see how finally works when return statement is present in try
block:
class JavaFinally{
public static void main(String args[])
{
System.out.println(JavaFinally.myMethod());
}
public static int myMethod()
{
try {
return 112;
}
finally {
System.out.println("This is Finally block");
System.out.println("Finally block ran even after return statement");
}
}}
Output of above program:
For example:
....try{
OutputStream osf = new FileOutputStream( "filename" );
OutputStream osb = new BufferedOutputStream(opf);
ObjectOutput op = new ObjectOutputStream(osb);
try{
output.writeObject(writableObject);
}
finally{
op.close();
}}catch(IOException e1){
System.out.println(e1);}...
Finally block without catch
A try-finally block is possible without catch block. Which means a try block can be
used with finally without having a catch block.
....try {
//try block
System.out.println("Inside try block");
System.exit(0)}catch (Exception exp) {
System.out.println(exp);}finally {
System.out.println("Java finally block");}....
In the above example if the System.exit(0) gets called without any exception then
finally won’t execute. However if any exception occurs while
calling System.exit(0) then finally block will be executed.
try-catch-finally block
Either a try statement should be associated with a catch block or with finally.
Since catch performs exception handling and finally performs the cleanup, the
best approach is to use both of them.
Syntax:
try {
//statements that may cause an exception}catch (…) {
//error handling code}finally {
//statements to be executed}
Examples of Try catch finally blocks
Example 1: The following example demonstrate the working of finally block when
no exception occurs in try block
class Example1{
public static void main(String args[]){
try{
System.out.println("First statement of try block");
int num=45/3;
System.out.println(num);
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("ArrayIndexOutOfBoundsException");
}
finally{
System.out.println("finally block");
}
System.out.println("Out of try-catch-finally block");
}}
Output:
class Example2{
public static void main(String args[]){
try{
System.out.println("First statement of try block");
int num=45/0;
System.out.println(num);
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("ArrayIndexOutOfBoundsException");
}
finally{
System.out.println("finally block");
}
System.out.println("Out of try-catch-finally block");
}}
Output:
Example 3: When exception occurs in try block and handled properly in catch block
class Example3{
public static void main(String args[]){
try{
System.out.println("First statement of try block");
int num=45/0;
System.out.println(num);
}
catch(ArithmeticException e){
System.out.println("ArithmeticException");
}
finally{
System.out.println("finally block");
}
System.out.println("Out of try-catch-finally block");
}}
Output:
The throws keyword does the same thing that try-catch does but there are some cases
where you would prefer throws over try-catch. For example: Lets say we have a
method myMethod() the statements inside this method can throw either
ArithmeticException or NullPointerException, in this case you can use try-catch as
shown below:
One way to overcome this problem is by using throws like this: declare the exceptions
in the method signature using throws and handle the exceptions where you are calling
this method by using try-catch.
Another advantage of using this approach is that you will be forced to handle the
exception when you call this method, all the exceptions that are declared using
throws, must be handled where you are calling this method else you will get
compilation error.
public void myMethod() throws ArithmeticException, NullPointerException{
// Statements that might throw an exception }
public static void main(String args[]) {
try {
myMethod();
}
catch (ArithmeticException e) {
// Exception handling statements
}
catch (NullPointerException e) {
// Exception handling statements
}}
Example of throws Keyword
In this example the method myMethod() is throwing two checked exceptions so we
have declared these exceptions in the method signature using throws Keyword. If we
do not declare these exceptions then the program will throw a compilation error.
In java we can create our own exception class and throw that exception using throw
keyword. These exceptions are known as user-defined or custom exceptions. In this
tutorial we will see how to create your own custom exception and throw it on a
particular condition.
To understand this tutorial you should have the basic knowledge of try-catch
block and throw in java.
Notes:
1. User-defined exception must extend Exception class.
2. The exception is thrown using throw keyword.
class JavaExample{
public static void main(String args[])
{
try{
int num1=30, num2=0;
int output=num1/num2;
System.out.println ("Result: "+output);
}
catch(ArithmeticException e){
System.out.println ("You Shouldn't divide a number by zero");
}
}}
Output of above program:
class JavaExample{
public static void main(String args[])
{
try{
int a[]=new int[10];
// This will throw exception as Array has
// only 10 elements and we are trying to access
// 12th element.
a[11] = 9;
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println ("ArrayIndexOutOfBounds Exception occurred");
System.out.println ("System Message: "+e);
}
}}
Output:
In the above example the array is initialized to store only 10 elements indexes 0 to 9.
Since we are trying to access element of index 11, the program is throwing this
exception.
class JavaExample{
public static void main(String args[])
{
try{
int num=Integer.parseInt ("XYZ") ;
System.out.println(num);
}catch(NumberFormatException e){
System.out.println("Number format exception occurred");
}
}}
Output:
A string is nothing but an array of string type. This exception occurs when you
try to access an index that doesn’t exist, similar to what we have seen in
ArrayIndexOutOfBoundsException.
Each character of a string object is stored in a particular index starting from 0.
For example: In the string “beginnersbook”, the char ‘b’ is stored at index 0, char
‘e’ at index 1 and so on.
To get a character present in a particular index of a string we can use a method
charAt(int) of java.lang.String where int argument is the index.
In the following example, the scope of the string “beginnersbook” is from index 0 to
12, however we are trying to access the char at index 40, which doesn’t exist, hence
the exception occurred.
class JavaExample{
public static void main(String args[])
{
try{
String str="beginnersbook";
System.out.println(str.length());
char c = str.charAt(40);
System.out.println(c);
}catch(StringIndexOutOfBoundsException e){
System.out.println("StringIndexOutOfBoundsException.");
}
}}
Output:
13StringIndexOutOfBoundsException.
Exception occurred because the referenced index was not present in the String.
class JavaExample{
public static void main(String args[])
{
try{
String str=null;
System.out.println (str.length());
}
catch(NullPointerException e){
System.out.println("NullPointerException..");
}
}}
Output:
NullPointerException..
Here, length() is the function, which should be used on an object. However in the
above example String object str is null so it is not an object due to
which NullPointerException occurred.
class JavaExample{
public static void main(String args[])
{
int x = 10;
int y = 10;
try{
int num= x/y;
System.out.println("Remaining statements inside try block");
}
catch(Exception ex)
{
System.out.println("Exception caught in catch block");
}
System.out.println("Statements Outside of try-catch");
}}
Output:
class JavaExample{
public static void main(String args[])
{
int x = 10;
int y = 0;
try{
int num= x/y;
System.out.println("Remaining statements inside try block");
}
catch(Exception ex)
{
System.out.println("Exception caught in catch block");
}
System.out.println("Statements Outside of try-catch");
}}
Output:
In the following example, the ArithmeticException occurred in try block but there is
no catch block that can handle ArithmeticException so after the execution of finally
block, a system generated error message is displayed.
Before exploring various input and output streams, let's look at 3 standard or
default streams that Java has to provide, which are also most commonly used:
System.in: This is the standard input stream (System.in) that is used to read
characters from the keyboard or any other standard input device.
System.out: This is the standard output stream (System.out) that is used to
produce the result of a program on an output device like the computer screen.
Here is a list of the various print functions that we use to output statements:
Now, we are going to discuss the main print function used with System.out which
are listed below:
1. print(): This method in Java is used to display a text on the console. This text is
passed as the parameter to this method in the form of String. This method prints the
text on the console and the cursor remains at the end of the text at the console. The
next printing takes place from just here.
Syntax:
System.out.print(parameter);
Example:
class Geeks {
public static void main(String[] args)
{
// using print()
// all are printed in the
// same line
System.out.print("GfG! ");
System.out.print("GfG! ");
System.out.print("GfG! ");
}
}
Output
GfG! GfG! GfG!
2. println(): This method in Java is also used to display a text on the console. It
prints the text on the console and the cursor moves to the start of the next line at the
console. The next printing takes place from the next line.
Syntax:
System.out.println(parameter);
Example:
class Geeks {
public static void main(String[] args)
{
// using println()
// all are printed in the
// different line
System.out.println("GfG! ");
System.out.println("GfG! ");
System.out.println("GfG! ");
}
}
Output
GfG!
GfG!
GfG!
3. printf(): This is the easiest of all methods as this is similar to printf in C. Note
that System.out.print() and System.out.println() take a single argument,
but printf() may take multiple arguments. This is used to format the output in Java.
Example:
// Printing a floating-point
// number with precision
System.out.printf("Formatted with precision: PI = %.2f%n", Math.PI);
float n = 5.2f;
n = 2324435.3f;
Output
Printing simple integer: x = 100
Formatted with precision: PI = 3.14
Formatted to specific width: n = 5.2000
Formatted to right margin: n = 2324435.2500
System.err Example
Types of Streams
Depending on the type of operations, streams can be divided into two primary
classes:
1. Input Stream: These streams are used to read data that must be taken as an input
from a source array or file or any peripheral device. For eg., FileInputStream,
BufferedInputStream, ByteArrayInputStream etc.
2. Output Stream: These streams are used to write data as outputs into an array or
file or any output peripheral device. For eg., FileOutputStream,
BufferedOutputStream, ByteArrayOutputStream etc.
Types of Streams Depending on the Types of File
Depending on the types of file, Streams can be divided into two primary classes
which can be further divided into other classes as can be seen through the diagram
below followed by the explanations.
1. ByteStream:This is used to process data byte by byte (8 bits). Though it has
many classes, the FileInputStream and the FileOutputStream are the most popular
ones. The FileInputStream is used to read from the source and FileOutputStream is
used to write to the destination.
Here is the list of various ByteStream Classes:
PrintStream This contains the most used print() and println() method
DataOutputStream This contains method for writing java standard data types.
Example:
// Java Program illustrating the// Byte Stream to copy// contents of one file to another
file.import java.io.*;public class Geeks { public static void main( String[]
args) throws IOException {
FileInputStream sourceStream = null; FileOutputStream targetStream =
null;
try { sourceStream = new FileInputStream("sorcefile.txt");
targetStream = new FileOutputStream("targetfile.txt");
// Reading source file and writing // content to target file byte by byte
int temp; while (( temp = sourceStream.read()) != -1)
targetStream.write((byte)temp); } finally { if (sourceStream != null)
sourceStream.close(); if (targetStream != null) targetStream.close();
} }}
Output:
Shows contents of file test.txt
PrintWriter This contains the most used print() and println() method
Example:
// Java Program illustrating that// we can read a file in a human-readable// format
using FileReader
// Accessing FileReader, FileWriter,// and IOExceptionimport java.io.*;
public class Geeks { public static void main(String[] args) throws IOException
{ FileReader sourceStream = null; try { sourceStream = new
FileReader("test.txt");
// Reading sourcefile and // writing content to target file //
character by character. int temp; while (( temp =
sourceStream.read())!= -1 ) System.out.println((char)temp); }
finally { // Closing stream as no longer in use if (sourceStream !=
null) sourceStream.close(); } }
********