Java Unit 4
Java Unit 4
1. Checked Exceptions:
Additionally, there is a third category of exceptions called Errors, which are not
considered exceptions in the conventional sense. Errors represent serious, non-
recoverable problems that occur at runtime, such as OutOfMemoryError or
StackOverflowError. Unlike exceptions, errors are not normally caught or handled
by applications, as they typically indicate severe issues with the JVM or
underlying system.
4. Give the class hierarchy in java related to exception handling. Briefly explain each class?
Ans: Throwable:
• Throwable is the superclass of all classes representing errors and exceptions in Java.
• It has two direct subclasses: Error and Exception.
Error:
• Error is the superclass of all classes representing serious, non-recoverable problems that
occur at runtime.
• Errors typically indicate problems with the JVM or underlying system and are not normally
caught or handled by applications.
• Examples of Error subclasses include OutOfMemoryError and StackOverflowError.
Exception:
• Exception is the superclass of all classes representing exceptions that can be caught and
handled by applications.
• It encompasses both checked exceptions and unchecked exceptions (runtime exceptions).
• Examples of Exception subclasses include IOException, SQLException,
NullPointerException, and ArrayIndexOutOfBoundsException.
RuntimeException:
• RuntimeException is a subclass of Exception and represents exceptions that occur due to
programming errors or unexpected conditions during runtime.
• Unlike checked exceptions, runtime exceptions do not need to be caught or declared
explicitly in the throws clause.
• Examples of RuntimeException subclasses include NullPointerException,
ArrayIndexOutOfBoundsException, and IllegalArgumentException.
IOException:
• IOException is a subclass of Exception and represents exceptions related to input-output
operations.
• It typically indicates problems with reading from or writing to streams, files, or other input-
output sources.
• Examples of IOException subclasses include FileNotFoundException and EOFException.
SQLException:
• SQLException is a subclass of Exception and represents exceptions related to database
access and manipulation.
• It typically indicates problems with executing SQL statements, connecting to databases, or
accessing database resources.
FileNotFoundException:
• FileNotFoundException is a subclass of IOException and represents an exception that
occurs when attempting to access a file that does not exist.
• It typically indicates that the specified file path is invalid or that the file does not exist at
the specified location.
NullPointerException:
• NullPointerException is a subclass of RuntimeException and represents an exception that
occurs when attempting to access or invoke a method on a null object reference.
• It typically indicates a programming error where code expects an object to be non-null but
encounters null instead.
ArrayIndexOutOfBoundsException:
• ArrayIndexOutOfBoundsException is a subclass of RuntimeException and represents an
exception that occurs when attempting to access an array element with an invalid index
(i.e., outside the bounds of the array).
• It typically indicates a programming error where code accesses an array with an index that
is too large or too small.
5. Wrirte a Java program that includes a try block and a catch clause that processes the
ArithmeticException generated by the division-by-zero error
Ans: public class ArithmeticExceptionHandling {
public static void main(String[] args) {
int dividend = 10;
int divisor = 0;
try {
// Attempting to perform division operation that may throw ArithmeticException
int result = dividend / divisor;
System.out.println("Result of division: " + result);
} catch (ArithmeticException e) {
// Handling the ArithmeticException
System.out.println("An error occurred: " + e.getMessage());
System.out.println("Please ensure the divisor is not zero.");
}
// Code continues execution after exception handling
System.out.println("Program continues execution...");
}
}
In this program:
• We attempt to perform a division operation where divisor is zero, which will result in an
ArithmeticException.
• The division operation is enclosed within a try block.
• If an ArithmeticException occurs during the division operation, the exception is caught by
the catch clause.
• Within the catch block, we handle the exception by printing an error message to the
console.
• The program continues execution after the exception handling block, demonstrating that
the program does not terminate abruptly due to the exception.
When you run this program, you'll see the following output:
An error occurred: / by zero
Please ensure the divisor is not zero.
Program continues execution...
6. Create a try block that is likely to generate 3 types of exceptions and then incorporate
necessary try blocks to catch and handle them appropriately?
Ans: Below is a Java program that creates a try block likely to generate three types of exceptions:
ArithmeticException, ArrayIndexOutOfBoundsException, and NumberFormatException. The
program then incorporates necessary try blocks to catch and handle each exception appropriately:
• We have a try block that contains three statements, each likely to generate one of the
specified exceptions.
• We use separate catch blocks to catch and handle each type of exception.
• Within each catch block, we print an appropriate error message along with the exception
message using e.getMessage().
• After handling the exceptions, the program continues execution, and a message "Program
continues execution..." is printed to the console.
When you run this program, you'll see the appropriate error messages for each caught exception:
7. What are the types of exceptions in Java API. Explain with examples
Ans:
Checked Exceptions:
• Checked exceptions are the exceptions that are checked at compile-time by the
compiler.
• They are subclasses of Exception (but not RuntimeException).
• Checked exceptions represent anticipated error conditions that can occur during
program execution and must be either caught (handled) using a try-catch block or
declared in the method's throws clause.
• Examples of checked exceptions in the Java API include:
• IOException: Represents exceptions related to input-output operations, such as
reading from or writing to files, streams, or network connections.
• FileNotFoundException: Represents an exception that occurs when attempting to
access a file that does not exist.
• ParseException: Represents exceptions related to parsing operations, such as
parsing strings into dates or numbers.
import java.io.*;
public class CheckedExceptionExample {
public static void main(String[] args) {
try {
BufferedReader reader = new BufferedReader(new FileReader("example.txt"));
String line = reader.readLine();
System.out.println("Read line: " + line);
reader.close();
} catch (IOException e) {
System.out.println("An error occurred while reading the file: " + e.getMessage());
}
}
}
Unchecked Exceptions (Runtime Exceptions):
• Unchecked exceptions are the exceptions that are not checked at compile-time by
the compiler.
• They are subclasses of RuntimeException.
• Unchecked exceptions typically represent programming errors or unexpected
conditions that can occur during runtime and do not need to be caught or declared
explicitly in the throws clause.
• Examples of unchecked exceptions in the Java API include:
• NullPointerException: Represents an exception that occurs when attempting to
access or invoke a method on a null object reference.
• ArrayIndexOutOfBoundsException: Represents an exception that occurs when
attempting to access an array element with an invalid index.
• NumberFormatException: Represents an exception that occurs when attempting to
parse a string into a numeric format, but the string does not contain a valid numeric
representation.
try {
// Calling a method that may throw the custom exception
example.performOperation(-5);
} catch (CustomException e) {
// Handling the custom exception
System.out.println("Custom exception caught: " + e.getMessage());
}
}
}
• We define a custom exception class CustomException that extends the Exception class.
This class has a constructor that accepts a message to be displayed when the exception is
thrown.
• We have a class Example with a method performOperation() that may throw the custom
exception CustomException if the value passed to it is negative.
• In the main() method of the UserDefinedExceptionExample class, we create an instance of
Example and call the performOperation() method with a negative value.
• We handle the custom exception using a try-catch block and print the message associated
with the exception.
When you run this program, you'll see the following output:
Custom exception caught: Value cannot be negative
9. Explain the life cycle of the thread?
Ans: The life cycle of a thread in Java refers to the various states a thread can be in during its
lifetime. Threads in Java follow a well-defined life cycle, transitioning between different states as
they are created, started, executed, paused, and terminated. The life cycle of a thread can be
represented by a finite state machine with different states.
• Once the start() method is called, the thread moves to the runnable state.
• In this state, the thread is ready to run, but it may not be running immediately because the
scheduler has not yet selected it to be the running thread.
• The thread scheduler selects threads in the runnable state to run based on thread priorities
and other scheduling algorithms.
Running:
• The thread moves from the runnable state to the running state when it's selected by the
thread scheduler to execute.
• In this state, the thread is actively executing its code.
• The run() method of the thread's Runnable object is being executed.
Blocked (Waiting):
• A thread moves to the blocked state when it's temporarily inactive or waiting for a resource.
• It may enter this state for reasons such as waiting for I/O operations to complete, waiting
for a lock, or waiting for a signal from another thread.
• The thread remains in the blocked state until the condition for which it was waiting is
satisfied.
Timed Waiting:
• Similar to the blocked state, a thread can also enter the timed waiting state when it's waiting
for a specific amount of time.
• This can occur when the thread calls methods such as Thread.sleep() or Object.wait() with
a timeout parameter.
Terminated (Dead):
• The thread moves to the terminated state when its run() method completes or when the
stop() method is called (though it's deprecated and should not be used).
• Once terminated, the thread cannot be restarted.
• After termination, the resources associated with the thread, such as memory and CPU
resources, are released.
10. What is a thread? Explain various stages of its life cycle.
Ans:
A thread is the smallest unit of execution within a process. In a multitasking operating system,
multiple threads can exist within a single process, allowing concurrent execution of multiple tasks.
Threads share the resources of the process to which they belong, including memory, file handles,
and other system resources.
New:
• The thread is in this state when it's created but not yet started.
• The Thread object has been instantiated, but the start() method has not been invoked.
• In this state, the thread has not yet been assigned system resources like CPU time.
Runnable:
• Once the start() method is called, the thread moves to the runnable state.
• In this state, the thread is ready to run, but it may not be running immediately because the
scheduler has not yet selected it to be the running thread.
• The thread scheduler selects threads in the runnable state to run based on thread priorities
and other scheduling algorithms.
Running:
• The thread moves from the runnable state to the running state when it's selected by the
thread scheduler to execute.
• In this state, the thread is actively executing its code.
• The run() method of the thread's Runnable object is being executed.
Blocked (Waiting):
• A thread moves to the blocked state when it's temporarily inactive or waiting for a resource.
• It may enter this state for reasons such as waiting for I/O operations to complete, waiting
for a lock, or waiting for a signal from another thread.
• The thread remains in the blocked state until the condition for which it was waiting is
satisfied.
Timed Waiting:
• Similar to the blocked state, a thread can also enter the timed waiting state when it's waiting
for a specific amount of time.
• This can occur when the thread calls methods such as Thread.sleep() or Object.wait() with
a timeout parameter.
Terminated (Dead):
• The thread moves to the terminated state when its run() method completes or when the
stop() method is called (though it's deprecated and should not be used).
• Once terminated, the thread cannot be restarted.
• After termination, the resources associated with the thread, such as memory and CPU
resources, are released.
11. Explain the process of creating threads using runnable Interface?
Ans: In Java, threads can be created by implementing the Runnable interface. This approach is
more flexible than extending the Thread class because a class can implement multiple interfaces,
but it can only extend one class.
Create a Runnable Implementation:
• Define a class that implements the Runnable interface.
• This class must provide an implementation for the run() method, which contains the code
that will be executed by the thread.
Instantiate the Runnable Object: Create an instance of the class implementing the Runnable
interface.
Create a Thread Object: Create an instance of the Thread class, passing the Runnable object as
a parameter to the constructor.
Start the Thread:
• Call the start() method on the Thread object to start the execution of the thread.
• The start() method internally calls the run() method of the Runnable object, executing the
code in a separate thread of execution.
class Counter {
private int count = 0;
// Synchronized method to increment the count
public synchronized void increment() {
count++;
}
// Synchronized method to decrement the count
public synchronized void decrement() {
count--;
}
// Method to get the current count value
public synchronized int getCount() {
return count;
}
}
public class SynchronizationExample {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
// Create and start multiple threads to increment and decrement the count
Thread incrementThread = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
Thread decrementThread = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.decrement();
}
});
incrementThread.start();
decrementThread.start();
class SharedResource {
private boolean flag = false; // Flag to indicate if a task is completed
// Method for thread 1 to perform a task
public synchronized void performTask1() throws InterruptedException {
// Wait until the flag is false (indicating task 2 is completed)
while (flag) {
wait();
}
System.out.println("Task 1 is performed"); // Perform task 1
flag = true; // Set flag to true
notify(); // Notify waiting thread
}
// Method for thread 2 to perform a task
public synchronized void performTask2() throws InterruptedException {
while (!flag) { // Wait until the flag is true (indicating task 1 is completed)
wait();
}
System.out.println("Task 2 is performed"); // Perform task 2
flag = false; // Set flag to false
notify(); // Notify waiting thread
}
}
public class ThreadCommunicationExample {
public static void main(String[] args) {
SharedResource sharedResource = new SharedResource();
Thread thread1 = new Thread(() -> { // Thread 1 performs task 1
try {
sharedResource.performTask1();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread thread2 = new Thread(() -> { // Thread 2 performs task 2
try {
sharedResource.performTask2();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread1.start();
thread2.start(); } }
15. Explain Daemon Threads with example?
Ans: In Java, daemon threads are a type of thread that runs in the background and provides services
to user threads. They are typically used for tasks that need to be performed periodically or
continuously in the background, such as garbage collection, monitoring, or background logging.
• Daemon threads are automatically terminated when all user threads (non-daemon threads)
complete their execution or when the JVM exits.
• They do not prevent the JVM from exiting even if they are running.
• Daemon threads should be used for background tasks that are not critical to the
application's functionality.
• Examples of daemon threads in Java include garbage collection threads, finalizer threads,
and some internal system threads.
16. Explain Thread groups with example?
Ans:
In Java, ThreadGroup is a class that represents a group of threads. It provides a convenient way to
manage and manipulate multiple threads as a single entity. Threads can be organized into thread
groups for easier management and monitoring.