UNIT 3-Exception Handling and MultiThreading
UNIT 3-Exception Handling and MultiThreading
Exception Handling basics- Multiple catch Clauses-Nested try Statements- Java’s Built-in Exceptions-
User defined Exception. Multithreaded Programming: Java Thread Model-Creating a Thread and
Multiple Threads – Priorities – Synchronization- Inter Thread Communication- Suspending- Resuming,
and Stopping Threads-Multithreading. Wrappers-Auto boxing.
Exception Handling is a mechanism to handle the runtime errors so that the normal flow of the
application can be maintained.
Exception: is an abnormal event that arises during the execution of the program and disrupts
the normal flow of the program. For example, if a user is trying to divide an integer by 0 then it is an
exception, as it is not possible mathematically.
There are various types of interruptions while executing any program like errors, exceptions,
and bugs. These interruptions can be due to programming mistakes or due to system issues.
Depending on the conditions they can be classified as exceptions and errors.
1.Exception:
➢ Exceptions are unwanted conditions that disrupt the flow of the program.
➢ Exceptions usually occur due to the code and can be recovered.
➢ Exceptions can be of both checked (exceptions that are checked by the compiler) and
unchecked (exceptions that cannot be checked by the compiler) type.
➢ They can occur at both compile time and ruin time.
➢ In Java, exceptions belong to java.lang.Exception class.
2.Error:
➢ An error is also an unwanted condition but it is caused due to lack of resources and
indicates a serious problem.
➢ Errors are irrecoverable, they cannot be handled by the programmers.
➢ Errors are of unchecked type only.
➢ They can occur only at run time.
➢ In java, errors belong to java.lang.Error class. Eg: OutOfMemoryError.
if there is a program with some lines of code and an exception occurs a mid-way after
executing certain lines of code, in this case, the execution terminates abruptly.
But if the programmer handles the exceptions explicitly, all the statements of code are
executed properly and the flow of the program is maintained.
class SampleCode
System.out.println("Hello World!");
int a = 10;
int b = 0;
System.out.println(a / b);
System.out.println("Bye.")
Output:
Hello World!
Exception in thread "main" java.lang.ArithmeticException: / by zero
at SampleException.main(SampleException.java:8)
In the above code, the first three lines in the main method are executed properly. At the 8th
line, an integer is divided by 0, which is not possible and an exception is raised by JVM (Java Virtual
Machine). In this case, the exception is not handled by the programmer which will halt the program in
between by throwing the exception, and the rest of the lines of code won't be executed.
Now, the above program is provided with try-catch statement to handle the exception.
class SampleCode
System.out.println("Hello World!");
int a = 10;
int b = 0;
try
catch( ArithmeticException e)
System.out.println(e);
System.out.println("Bye.")
}
Output:
Bye
Now the exception is handled using try cath block and the flow of the code sequence is maintained.
Hence the remaining statements is also printed.
The JVM firstly checks whether the exception is handled or not. If exception is not handled, JVM
provides a default exception handler that performs the following tasks:
But if the application programmer handles the exception, the normal flow of the application is
maintained, i.e., rest of the code is executed.
Exception Hierarchy
The java.lang.Throwable class is the root class of Java Exception hierarchy inherited by two subclasses:
Exception and Error. The hierarchy of Java Exception classes is given below:
There are mainly two types of exceptions: checked and unchecked. An error is considered as
the unchecked exception. However, according to Oracle, there are three types of exceptions namely:
1. Checked Exception
2. Unchecked Exception
3. Error
1) Checked Exception
➢ Checked exceptions are those exceptions that are checked at compile time by the
compiler.
➢ The program will not compile if they are not handled.
➢ These exceptions are child classes of the Exception class.
➢ IOException, ClassNotFoundException, InvocationTargetException, and SQL Exception are a
few of the checked exceptions in Java.
2) Unchecked Exception
➢ Unchecked exceptions are those exceptions that are checked at run time by JVM, as the
compiler cannot check unchecked exceptions,
➢ The programs with unchecked exceptions get compiled successfully but they give runtime
errors if not handled.
➢ These are child classes of Runtime Exception Class.
➢ ArithmeticException, NullPointerException, NumberFormatException,
IndexOutOfBoundException are a few of the unchecked exceptions in Java.
3) Error
Java exception handling is managed via five keywords: try, catch, throw, throws, and finally
• Try block : contains the program statements that may raise an exception. The try block must
be followed by either catch or finally.
• Catch block: is used to handle the raised exception. It must be preceded by try block and can
be followed by finally block later.
• Throw keyword is used to explicitly throw an exception.
• Throws keyword is used to declare an exception. It specifies that there may occur an
exception in the method. It doesn't throw an exception. It is always used with method
signature.
• Finally block contains statements that must be executed after the try block. Finally block code
is executed whether an exception is handled or not. Finally block is used to execute important
statements such as closing statement, release the resources, and release memory also.
Java try block is used to enclose the code that might throw an exception.
Syntax: of try-catch
try
{
// code that may throw an exception
}
catch(Exception_class_Name ref)
{
Syntax: of try-finally
try
{
// code that may throw an exception
}
finally
{
Java catch block is used to handle the Exception by declaring the type of exception within the
parameter. The declared exception must be the parent class exception ( i.e., Exception) or the
generated exception type. However, the good approach is to declare the generated type of exception.
Multiple Catch Clauses:
A try block can be followed by one or more catch blocks. Each catch block must contain a
different exception handler. Hence multi-catch block is used to perform different tasks at the
occurrence of different exceptions.
At a time only one exception occurs and at a time only one catch block is executed. All catch
blocks must be ordered from most specific to most general, i.e., catch for ArithmeticException must
come before catch for Exception.
Output:
ArrayIndexOutOfBounds Exception occurs
rest of the code
try{
String s=null;
System.out.println(s.length());
}
catch(ArithmeticException e)
{
System.out.println("Arithmetic Exception occurs");
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("ArrayIndexOutOfBounds Exception occurs");
}
catch(Exception e)
{
System.out.println("Parent Exception occurs");
}
System.out.println("rest of the code");
}
}
Output:
Parent Exception Occurs
rest of the code
In this Program, NullPointerException is generated but the corresponding exception type is
not provided. In such case, the catch block containing the parent exception class Exception will be
invoked.
Syntax:
....
//main try block
try
{
statement 1;
statement 2;
//try catch block within another try block
try
{
statement 3;
statement 4;
//try catch block within nested try block
try
{
statement 5;
statement 6;
}
catch(Exception e2)
{
//exception message
}
}
catch(Exception e1)
{
//exception message
}
}
//catch block of parent (outer) try block
catch(Exception e3)
{
//exception message
}
....
Output:
going to divide by 0
java.lang.ArithmeticException:/by Zero
java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 4
other statement
normal flow
Let's consider the following example. Here the try block within nested try block (inner try block
2) do not handle the exception. The control is then transferred to its parent try block (inner try block
1). If it does not handle the exception, then the control is transferred to the main try block (outer try
block) where the appropriate catch block handles the exception. It is termed as nesting.
public class NestedTryBlock2 {
try {
try {
try {
int arr[] = { 1, 2, 3, 4 };
System.out.println(arr[10]);
// to handles ArithmeticException
catch (ArithmeticException e) {
System.out.println("Arithmetic exception");
// to handle ArithmeticException
catch (ArithmeticException e) {
System.out.println("Arithmetic exception");
}
// to handle ArrayIndexOutOfBoundsException
System.out.print(e4);
System.out.print("Exception");
Output:
When any try block does not have a catch block for a particular exception, then the catch block of the
outer (parent) try block are checked for that exception, and if it matches, the catch block of outer try
block is executed.
If none of the catch block specified in the code is unable to handle the exception, then the Java
runtime system will handle the exception. Then it displays the system generated message for that
exception.
Java’s finally block:
➢ Java finally block is a block used to execute important code such as closing the connection, etc.
➢ Java code within the finally block is always executed whether an exception is handled or not.
Therefore, it contains all the necessary statements that need to be printed regardless of the
exception occurs or not.
➢ The finally block follows the try-catch block.
In the following example, the Java program does not throw any exception, and the finally block
is executed after the try block.
class TestFinallyBlock {
public static void main(String args[]){
try{
//below code do not throw any exception
int data=25/5;
System.out.println(data);
}
//catch won't be executed
catch(NullPointerException e){
System.out.println(e);
}
//executed regardless of exception occurred or not
finally {
System.out.println("finally block is always executed");
}
System.out.println("rest of the code...");
}
}
Output:
5
finally block is always executed
rest of the code
Case 2: When an exception occur but not handled by the catch block
Here, the code throws an exception however the catch block cannot handle it. Despite this, the
finally block is executed after the try block and then the program terminates abnormally.
public class TestFinallyBlock1{
public static void main(String args[]){
try {
In the following example, the Java program throws an exception and the catch block handles
the exception. Later the finally block is executed after the try-catch block. Further, the rest of the code
is also executed normally.
Java’s Built-in exceptions are the exceptions which are available in Java libraries. These exceptions
are suitable to explain certain error situations.
1) Checked Exception
Checked exceptions are also known as compile-time exceptions as these exceptions are
checked by the compiler during the compilation process to confirm whether the exception is
handled by the programmer or not. If not, then the system displays a compilation error.
The classes that directly inherit the Throwable class except RuntimeException and Error are
known as checked exceptions. For example, IOException, SQLException, etc. Checked exceptions
are checked at compile-time.
2) Unchecked Exception
The unchecked exceptions are those exceptions that occur during the execution of the
program. Hence they are also referred to as Runtime exceptions. These exceptions are generally
ignored during the compilation process.
The classes that inherit the RuntimeException are known as unchecked exceptions. For
example, ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException, etc.
Unchecked exceptions are not checked at compile-time, but they are checked at runtime.
3) Error
import java.io.*;
// Example of FileNotFoundException
public class Main {
System.out.println(fileReader.read());
fileReader.close();
}
}
Output:
Main.java:8: error: unreported exception FileNotFoundException; must be caught or
declared to be thrown
How to handle IOException in java?
IOException can be handled using try and catch blocks to handle the exception.
import java.io.*;
// Example of FileNotFoundException
public class Main {
try {
// Creating an instance of FileReader class
FileReader fileReader = new FileReader("Test.txt");
System.out.println(fileReader.read());
fileReader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
The above program compiles successfully and does not thrown any exception at compile time.
However, if the specified file does not exist or any other error occurs, the code within catch block
executes as shown in the below output.
Output:
Output:
Can’t divide a number by 0
2.ArrayIndexOutOfBounds Exception: It is thrown to indicate that an array has been accessed with
an illegal index. The index is either negative or greater than or equal to the size of the array.
class ArrayIndexOutOfBound_Demo {
public static void main(String args[])
{
try {
int a[] = new int[5];
a[6] = 9; // accessing 7th element in an array of
// size 5
}
catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array Index is Out Of Bounds");
}
}
}
Output:
3. ClassNotFoundException: This exception is raised when program try to access a class whose
definition is not found.
4. FileNotFoundException: This exception is raised when a file is not accessible or does not open.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
class File_notFound_Demo {
Output:
5. Null Pointer Exception: This exception is raised when referring to the members of a null object. Null
represents nothing
class NullPointer_Demo {
public static void main(String args[])
{
try
{
String a = null; // null value
System.out.println(a.charAt(0));
}
catch (NullPointerException e)
{
System.out.println("NullPointerException..");
}
}
}
Output: NullPointerException
User-Defined Exception:
Java user-defined exception is a custom exception created and throws that exception using
a keyword ‘throw’. It is done by extending a class ‘Exception’.
Scenario:
In any banking application, the major modules are deposits and withdrawals. When
performing a withdrawal from a bank account, it is required to validate the minimum balance in the
account.
To validate this requirement Java didn’t provide any specific exception class. Hence to
handle this requirement, a user-defined exception MinimumAccountBalance may be created.
Example Program:
else
{
System.out.println("Please Take The Money : " + n);
}
}
catch (MinimumAccountBalance mab)
{
mab.printStackTrace();
}
}
}
Output:
D:\javaprograms>javac UserDefinedException.java
D:\javaprograms>java UserDefinedException
Enter amount to withdrawal
500
Insufficient funds ! your Current balance is 100.0
at UserDefinedException.main(UserDefinedException.java:27)
D:\javaprograms>java UserDefinedException
Enter amount to withdrawal
50
Please Take The Money : 50
Multithreaded Programming: Java Thread Model
Multitasking is a process of executing multiple tasks simultaneously. The concept of
multitasking is to utilize the CPU at its Maximum. Multitasking can be achieved in two ways:
o Each process has an address in memory. In other words, each process allocates a
separate memory area.
o A process is heavyweight.
o Cost of communication between the process is high.
o Context Switching from one process to another is costly and it requires some time
for saving and loading registers, memory maps, updating lists, etc.
Process
Process simply means a program in execution. Processes have their own separate address
space (their own code & data) & use more resources and hence they are termed as heavyweight
process.
The above diagram shows how the resources are shared in two different processes vs two
threads in a single process.
Thread
➢ Thread is a sequential flow of tasks within a process. Threads are used to increase the
performance of the applications.
➢ Each thread has its own program counter, stack, and set of registers. But the threads of a
single process might share the same code and data/file. Threads are also termed as
lightweight processes as they share common resources.
➢ Eg: While playing a movie on a device the audio and video are controlled by different
threads in the background.
The above diagram shows the difference between a single-threaded process and a multithreaded
process and the resources that are shared among threads in a multithreaded process.
Multithreading
In Multithreading, the idea is to divide a single process into multiple threads instead of
creating a whole new process. Multithreading is done to achieve parallelism and to improve the
performance of the applications
i) Resource Sharing:
Threads of a single process share the same resources such as code, data/file.
ii) Responsiveness:
Program responsiveness enables a program to run even if part of the program is blocked or
executing a lengthy operation. Thus, increasing the responsiveness to the user.
iii)Economy:
It is more economical to use threads as they share the resources of a single process. On the
other hand, creating processes is expensive.
Process Vs Thread
Process Thread
Processes use more resources and hence
Threads share resources and hence they are
they are termed as heavyweight
termed as lightweight processes.
processes.
Creation and termination times of Creation and termination times of threads are
processes are slower. faster compared to processes.
Processes have their own code and
Threads share code and data/file within a process.
data/file.
Communication between processes is
Communication between threads is faster.
slower.
Context Switching in processes is slower.Context switching in threads is faster.
Threads, on the other hand, are interdependent.
Processes are independent of each other. (i.e they can read, write or change another
thread’s data)
Eg: Opening two different browsers. Eg: Opening two tabs in the same browser.
Types of Thread:
1.Userlevel Thread
User-level threads are implemented and managed by the user and the kernel is not aware of it.
• User-level threads are implemented using user-level libraries and the OS does not recognize
these threads.
• User-level thread is faster to create and manage compared to kernel-level thread.
• Context switching in user-level threads is faster.
• If one user-level thread performs a blocking operation then the entire process gets blocked.
Eg: POSIX threads, Java threads, etc.
2. Kernel level Thread:
Kernel level threads are implemented and managed by the OS.
• Kernel level threads are implemented using system calls and Kernel level threads are
recognized by the OS.
• Kernel-level threads are slower to create and manage compared to user-level threads.
• Context switching in a kernel-level thread is slower.
• Even if one kernel-level thread performs a blocking operation, it does not affect other threads.
Eg: Window Solaris.
Advantages of Threading:
➢ Once this polling mechanism returns with, For example., a signal that a network file is
ready to be read, then the event loop dispatches control to the appropriate event
handler. Until this event handler returns, nothing else can happen in the program. This
wastes CPU time. It can also result in one part of a program dominating the system and
preventing any other events from being processed.
➢ In general, in a single threaded environment, when a thread blocks (that is, suspends
execution) because it is waiting for some resource, the entire program stops running.
Java’s Multithreading Features Support in both Single Core Systems and Multi core Systems.
In a single-core system, concurrently executing threads share the CPU, with each thread
receiving a slice of CPU time. Therefore, in a single-core system, two or more threads do not
actually run at the same time, but idle CPU time is utilized.
In multicore systems, it is possible for two or more threads to actually execute simultaneously.
This ability can improve program efficiency and increase the speed of operations.
Thread States:
A thread in java goes through five states in the span of its creation to its termination
1. New state: Whenever a new thread is created, it is always in the new state. For a thread in the
new state, the code has not been run yet and thus has not begun its execution.
2. Active state: A thread moves from the new state to the active state when the thread invokes
the start() method. The thread in the active state can be in a runnable state or a running state.
Runnable state: After the creation of thread in java, when the thread is ready to run, it is
moved from the new state to the runnable state. During the runnable state, the thread
may be running or may be ready to run at any given instant of time. In the runnable state,
there is a queue where the threads lie.
Running state: A thread is moved from the runnable state to the running state by the
thread scheduler for its execution. By the running state, the thread gets the CPU for its
execution. Always a fixed duration of execution time is allocated to a thread in java.
3. Waiting or blocked state: Whenever a thread in java goes to an inactive state for some time (period
i.e. not permanently), then the thread is present in the waiting or blocked state.
Whenever the main thread calls the join() method (to attach itself with other thread(s)), then
the main method or main thread goes into the waiting state. After invoking the join() method,
the main thread waits for its child thread to be executed first.
When the child thread completed its execution, it sends a signal back to the main thread. after
getting the completion signal for the child thread, the main thread is moved from the waiting
state to the active state.
Sometimes when a thread is working on data that is being used by some other thread then the
current thread waits to acquire a lock on the shared data. This state is referred to as the
locking state.
4.Timed Waiting state: when a process is waiting, and it continues to wait for a longer duration
then the process is said to be in the timed waiting state. A thread can also move in the timed
waiting state if the thread invokes a method with the time-out parameter. The thread exits the
timed waiting state when the timeout is completed or the waiting resources are gained.
5. Terminated state: When the thread completes its instruction cycle (completes execution), the
thread goes into the termination state. A thread may also go into the termination state due to
some error. When the thread is not handled correctly or when some other execution(s) is raised by
the thread then the thread is terminated as abnormal termination.
When starts the JVM or the Java Virtual Machine, a single thread (typically called the main method)
is started. This main thread continues and executed other threads until the following conditions are
met:
2. All the other threads have exited after executing their instructions.
Thread Scheduler:
A thread in java is executed as per the priority. The thread with higher priority is executed first
then the threads with lower priorities are executed.
CREATING A THREAD AND MULTIPLE THREADS
Thread class provide constructors and methods to create and perform operations on a thread.
Thread class extends Object class and implements Runnable interface.
i) Thread()
iii) Thread(Runnable r)
2. public void start(): starts the execution of the thread. JVM calls the run() method on the thread.
3. public void sleep(long miliseconds): Causes the currently executing thread to sleep (temporarily
cease execution) for the specified number of milliseconds.
10. public void join(long miliseconds): waits for a thread to die for the specified miliseconds.
The start() method of Thread class is used to start a newly created thread. It performs the following
tasks:
System.out.println("thread is running...");
t1.start();
Output:
thread is running…
The Runnable interface should be implemented by any class whose instances are intended to
be executed by a thread. Runnable interface have only one method named run().
thread is running…
My first thread
Creating Multiple Threads
Output:
D:\javaprograms>java MultiThreadDemo
New thread:Thread[#20,One,5,main]
New thread:Thread[#21,Two,5,main]
New thread:Thread[#22,Three,5,main]
Three:5
Two:5
One:5
Main thread exiting.
Two:4
Three:4
One:4
Three:3
Two:3
One:3
Two:2
Three:2
One:2
Two:1
Three:1
One:1
Three exiting.
Two exiting.
One exiting.
THREAD PRIORITIES
Thread priorities are used by the thread scheduler to decide when each thread should be
allowed to run. Each thread has a priority. Priorities are represented by a number between 1 and 10.
In most cases, the thread scheduler schedules the threads according to their priority .
➢ To set a thread’s priority, use the setPriority( ) method, which is a member of Thread
class.
Here, level specifies the new priority setting for the calling thread. The value of level
must be within the range MIN_PRIORITY and MAX_PRIORITY. Currently, these values are 1 and 10,
respectively. To return a thread to default priority, specify NORM_PRIORITY, which is currently 5.
These priorities are defined as static final variables within Thread.
➢ To obtain the current priority, use the getPriority() method which is a member of Thread
class
➢ When two or more threads need access to a shared resource, they need some way to ensure
that the resource will be used by only one thread at a time. The process by which this is
achieved is called synchronization.
➢ There are two types of thread synchronization mutual exclusive and inter-thread
communication.
1. Mutual Exclusive
i. Synchronized method.
ii. Synchronized block
iii. Static Synchronization
2. Inter-thread communication (Cooperation)
Key to synchronization is the concept of the monitor. A monitor is an object that is used as a
mutually exclusive lock.
Only one thread can own a monitor at a given time. When a thread acquires a lock, it is said to
have entered the monitor. All other threads attempting to enter the locked monitor will be
suspended until the first thread exits the monitor.
These other threads are said to be waiting for the monitor. A thread that owns a monitor can
reenter the same monitor if it so desires.
class Table{
void printTable(int n){//method not synchronized
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
class TestSynchronization1{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output:
5
100
10
200
15
300
20
400
25
500
Java Synchronized Method
A method which is declared with the keyword synchronized is known as synchronized method.
Synchronized method is used to lock an object for any shared resource. When a thread invokes a
synchronized method, it automatically acquires the lock for that object and releases it when the
thread completes its task.
}
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
o wait()
o notify()
o notifyAll()
1) Wait() Method
The wait() method causes current thread to release the lock and wait until either another
thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of
time has elapsed. In case, the wait() method doesn’t take argument, it waits indefinitely for any other
thread to call notify() or notifyAll() method on the object to wake up the current thread.
The current thread must own this object's monitor, so it must be called from the synchronized
method only otherwise it will throw exception.
Method Description
public final void wait(long timeout)throws It waits for the specified amount of
InterruptedException time.
2) notify() Method
The notify() method wakes up a single thread that is waiting on this object's monitor. If any
threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary
and occurs at the discretion of the implementation.
Syntax:
public final void notify()
3) notifyAll() Method
Syntax:
public final void notifyAll()
MyThread1(Customer c)
{
this.c=c;
}
class Test
{
public static void main(String args[])
{
Customer c=new Customer();
MyThread1 t1 = new MyThread1(c);
MyThread2 t2 = new MyThread2(c);
t1.start();
t2.start();
}
}
Output:
D:\javaprograms>java Test
going to withdraw...Withdrawal amount is15000
Actual Balance is10000
Less balance; waiting for deposit...
going to deposit...
Balance before deposit:10000
Balance amount after deposit... 20000
Balance amount after withdraw...5000
An interrupted thread's execution can be picked back up by notifying the waiting thread using
the notify() method.
To halt a running thread, use a boolean flag to signal the thread to stop gracefully.
try
{
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread one");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming thread one");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
}
catch(InterruptedException e)
{
System.out.println("Main thread Interrupted");
}
Output:
New Thread:Thread[#20,One,5,main]
New Thread:Thread[#21,Two,5,main]
Two:15
One:15
One:14
Two:14
Two:13
One:13
One:12
Two:12
One:11
Two:11
Suspending thread one
Two:10
Two:9
Two:8
Two:7
Two:6
Resuming thread one
One:10
Suspending thread Two
One:9
One:8
One:7
One:6
Resuming thread Two
One:5
Two:5
waiting for threads to finish.
One:4
Two:4
One:3
Two:3
One:2
Two:2
One:1
Two:1
Oneexiting.
Twoexiting.
Main thread exiting.
Wrappers
A wrapper class in Java is used to represent a primitive data type as an object. For
example, the Integer wrapper class can be used to represent and perform operations on integer
values.
For Example:
Integer myNumber = new Integer(10);
int value = myNumber.intValue();
System.out.println(value); // Output: 10
Java provides wrapper classes for each primitive data type. The wrapper classes are: -
Integer - Byte - Short - Long - Float - Double - Character - Boolean
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double
Need of Wrapper class in java:
Wrapper classes provide additional functionality and features that are not available with
primitive data types. It allows to treat primitive values as objects and provide methods for
conversions, comparisons, and other operations. Wrapper classes are also useful in Java collections
and when working with APIs that require objects.
class Main {
public static void main(String[] args) {
// create primitive types
int a = 5;
double b = 5.65;
//converts into wrapper objects
Integer aObj = Integer.valueOf(a);
Double bObj = Double.valueOf(b);
if(aObj instanceof Integer) {
System.out.println("An object of Integer is created.");
System.out.println("The value stored in aObj is:"+aObj);
}
if(bObj instanceof Double) {
System.out.println("An object of Double is created.");
System.out.println("The value stored in bObj is:"+bObj);
}
}
}
Output:
D:\javaprograms>javac MainWrapper.java
D:\javaprograms>java MainWrapper
An object of Integer is created.
The value stored in aObj is:5
An object of Double is created.
The value stored in bObj is:5.65
Autoboxing:
Autoboxing is when the Java compiler performs the automatic conversion of the primitive data
types to the object of their corresponding wrapper classes. For example, converting an int to Integer,
a double to Double, etc.
Output:
50
50
50
Unboxing:
Unboxing is automatically converting an object of a wrapper type (Integer, for example) to its
corresponding primitive (int) value.
The Java compiler applies unboxing when an object of a wrapper class is:
• Passed as a parameter to a method that expects a value of the corresponding primitive type.
• Assigned to a variable of the corresponding primitive type.
Example Program:
//Unboxing example of Integer to int and Character to char
public class UnboxingExample {
public static void main(String args[]) {
Character ch = 's';
//Unboxing - Character object to primitive conversion
char s = ch;
Integer a = new Integer(5);
//Converting Integer to int explicitly
int first = a.intValue();
//Unboxing, now compiler will write a.intValue() internally
int second = a;
System.out.println(a);
System.out.println(first);
System.out.println(second);
}
}
Output:
5
5
5