0% found this document useful (0 votes)
26 views

Java IAT3

Uploaded by

sunita.sheoran14
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views

Java IAT3

Uploaded by

sunita.sheoran14
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Q. What is Thread? Explain the two ways of creating a Thread in Java.

A. In Java, a thread is a lightweight process, a separate path of execution within a


program. Threads allow concurrent execution of multiple tasks within a single
program, enabling applications to perform multiple operations simultaneously.
There are two main ways to create a thread in Java:
1. Extending the Thread class:
​ This method involves creating a new class that extends the Thread class and
overriding its run() method to define the behavior of the thread. The run()
method contains the code that will be executed when the thread is started.
Here's an example:

class MyThread extends Thread {
public void run() {
System.out.println("This is a thread created by extending Thread class.");
}
}

public class Main {


public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start(); // Start the thread
}
}

2. Implementing the Runnable interface:
​ This method involves creating a class that implements the Runnable interface
and providing an implementation for its run() method. This approach is often
preferred because it allows for better encapsulation by separating the thread's
behavior from the thread's execution logic. Here's an example:

class MyRunnable implements Runnable {
public void run() {
System.out.println("This is a thread created by implementing Runnable
interface.");
}
}

public class Main {


public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start(); // Start the thread
}
}

In both cases, the start() method is called on the thread object to begin its
execution. The Java Virtual Machine (JVM) schedules the thread for execution, and
the code inside the run() method gets executed concurrently with other threads in
the program.

Q. Write a java program to illustrate thread creation using Runnable interface


and Thread class.
A. // Thread creation using Runnable interface
class MyRunnable implements Runnable {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Thread created using Runnable: " + i);
try {
Thread.sleep(500); // Sleep for 500 milliseconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

// Thread creation using Thread class


class MyThread extends Thread {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Thread created using Thread class: " + i);
try {
Thread.sleep(500); // Sleep for 500 milliseconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

public class Main {


public static void main(String[] args) {
// Creating and starting a thread using Runnable interface
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable);
thread1.start();

// Creating and starting a thread using Thread class


MyThread myThread = new MyThread();
myThread.start();
}
}

Q.What is an exception? With syntax and example, explain exception handling


mechanism in Java.
A.An exception in Java is an event that occurs during the execution of a program
that disrupts the normal flow of instructions. Exceptions are objects that represent
exceptional conditions or errors that arise during the execution of a program.
Exception handling in Java is a mechanism to deal with these exceptional situations
in a controlled and graceful manner, preventing the program from crashing abruptly.
Java provides built-in mechanisms for handling exceptions using try, catch, finally,
and throw keywords.
Here's the syntax for exception handling in Java:

try {
// Code that may throw an exception
} catch (ExceptionType1 e1) {
// Code to handle ExceptionType1
} catch (ExceptionType2 e2) {
// Code to handle ExceptionType2
} finally {
// Code that always gets executed, regardless of whether an exception is
thrown or caught
}

Now, let's see an example of exception handling in Java:

public class ExceptionHandlingExample {


public static void main(String[] args) {
try {
int result = divide(10, 0); // Attempting to divide by zero
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Error: Division by zero is not allowed.");
} finally {
System.out.println("Inside finally block.");
}
}

public static int divide(int dividend, int divisor) {


return dividend / divisor;
}
}

Explanation of the example:


​ We have a divide method that takes two integers as parameters and attempts
to divide the dividend by the divisor.
​ In the main method, we have a try block where we call the divide method with
parameters 10 and 0, which will cause an ArithmeticException to be thrown
because dividing by zero is not allowed.
​ The catch block catches the ArithmeticException and handles it by printing
an error message.
​ The finally block always gets executed, regardless of whether an exception
is thrown or caught. It is used for cleanup code that needs to be executed
whether an exception occurs or not.
​ In this example, since an exception occurs during the execution of the try
block, the code inside the catch block is executed, followed by the code inside
the finally block.

Output of the example:
Error: Division by zero is not allowed.
Inside finally block.

This demonstrates how Java's exception handling mechanism allows us to


gracefully handle errors and prevent the program from crashing abruptly.

Q.Define Exception. Write a program which contains one method which will
throw IllegalAccessException and use proper exception handlers so that
exception should be printed in the calling function.
A.An exception in Java is an event that occurs during the execution of a program that
disrupts the normal flow of instructions. Exceptions are objects that represent
exceptional conditions or errors that arise during the execution of a program.
In Java, there are two types of exceptions: checked exceptions and unchecked
exceptions. Checked exceptions must be handled explicitly in the code, either by
using a try-catch block or by declaring the exception using the throws keyword in
the method signature. Unchecked exceptions, on the other hand, are not required to
be handled explicitly in the code.
Here's a program that contains a method that throws IllegalAccessException, and
proper exception handling is used in the calling function to catch and print the
exception:

public class ExceptionExample {


public static void main(String[] args) {
try {
// Call method that throws IllegalAccessException
doSomething();
} catch (IllegalAccessException e) {
// Handle the exception
System.out.println("Caught exception: " + e.getMessage());
}
}

public static void doSomething() throws IllegalAccessException {


// Simulate throwing IllegalAccessException
throw new IllegalAccessException("Illegal access exception occurred");
}
}

Explanation of the program:


​ The doSomething() method is declared with a throws clause specifying that it
may throw an IllegalAccessException.
​ In the main method, we call the doSomething() method within a try-catch
block.
​ Inside the try block, we call the doSomething() method, which throws an
IllegalAccessException.
​ If an IllegalAccessException is thrown, it is caught by the catch block, and a
message is printed to indicate that the exception has been caught.

Output of the program (when doSomething() throws IllegalAccessException):
Caught exception: Illegal access exception occurred

This program demonstrates proper exception handling in Java, where the exception
thrown by the doSomething() method is caught and handled gracefully in the calling
function.

Q.Explain packages and its types. Explain import command in Java with an
examples.
A.In Java, a package is a way of organizing and grouping related classes and
interfaces. Packages provide a mechanism for creating namespaces, which helps
avoid naming conflicts and organizes classes and interfaces into logical units.
Packages also facilitate access control by allowing classes to be grouped together
and controlled as a unit.
There are two main types of packages in Java:
1. Built-in Packages: These are the packages that are included with the Java
Development Kit (JDK) and are part of the Java API. Examples of built-in
packages include java.lang, java.util, java.io, etc.
2. User-defined Packages: These are the packages that are created by the user
to organize their own classes and interfaces. User-defined packages help in
managing large projects by grouping related classes and interfaces together.

Import Command in Java:


The import command in Java is used to make classes and interfaces from other
packages available to your current source file. It enables you to use classes and
interfaces defined in other packages in your Java program.
Here's the syntax for importing a specific class or interface from a package:
import package_name.class_name;

And here's the syntax for importing all classes and interfaces from a package:
import package_name.*;

Now, let's see some examples of using the import command in Java:

// Importing a specific class from a package


import java.util.ArrayList;

public class MyClass {


public static void main(String[] args) {
// Creating an object of the imported class
ArrayList<String> myList = new ArrayList<>();
}
}

In this example, we are importing the ArrayList class from the java.util package.
This allows us to use the ArrayList class in our MyClass without fully qualifying its
name.

// Importing all classes from a package


import java.util.*;

public class MyClass {


public static void main(String[] args) {
// Creating objects of classes from the imported package
ArrayList<String> myList = new ArrayList<>();
HashMap<Integer, String> myMap = new HashMap<>();
}
}

In this example, we are importing all classes from the java.util package using the
* wildcard. This allows us to use any class or interface from the java.util package
in our MyClass without fully qualifying their names.

Q.What is meant by thread priority? How is it assigned and how to get the thread
priority?
A.Thread priority in Java is a mechanism provided by the Java Virtual Machine
(JVM) to control the scheduling of threads. Each thread in Java is assigned a priority
that determines its importance to the scheduler relative to other threads. Threads
with higher priority are given preference by the scheduler and are more likely to be
scheduled for execution before threads with lower priority. However, thread priority is
only a hint to the scheduler and not an absolute guarantee of execution order.
In Java, thread priority is represented by an integer value ranging from 1 to 10, where
1 is the lowest priority and 10 is the highest priority. The default priority of a thread is
5.
Thread priorities are assigned using the setPriority(int priority) method of the
Thread class. This method sets the priority of the thread to the specified integer
value.
Here's how you can assign a priority to a thread in Java:
Thread thread = new Thread();
thread.setPriority(Thread.MAX_PRIORITY); // Set priority to the highest value
(10)

To get the priority of a thread, you can use the getPriority() method of the Thread
class. This method returns the priority of the thread as an integer value.
Here's how you can get the priority of a thread in Java:
Thread thread = Thread.currentThread();
int priority = thread.getPriority(); // Get the priority of the current thread
System.out.println("Thread priority: " + priority);

It's important to note that the exact behavior of thread priorities may vary between
different operating systems and JVM implementations. Additionally, reliance on
thread priorities for controlling thread execution order is generally discouraged
because it can lead to platform-dependent behavior and may not always produce the
desired results. Therefore, thread priorities should be used judiciously and in
conjunction with other concurrency control mechanisms, such as synchronization
and locks.

Q.Develop a program to demonstrate Thread priorities in Java


A.class MyThread extends Thread {
public MyThread(String name) {
super(name);
}

public void run() {


System.out.println(getName() + " is running with priority " + getPriority());
}
}

public class ThreadPriorityDemo {


public static void main(String[] args) {
// Create threads with different priorities
MyThread thread1 = new MyThread("Thread 1");
MyThread thread2 = new MyThread("Thread 2");
MyThread thread3 = new MyThread("Thread 3");

// Set priorities
thread1.setPriority(Thread.MIN_PRIORITY); // Set minimum priority (1)
thread2.setPriority(Thread.NORM_PRIORITY); // Set normal priority (5)
thread3.setPriority(Thread.MAX_PRIORITY); // Set maximum priority (10)
// Start threads
thread1.start();
thread2.start();
thread3.start();
}
}

Q.What is the need for synchronization? Explain with an example, how


synchronization is implemented in Java
A. In Java, synchronization is a mechanism that allows multiple threads to access
shared resources in a coordinated manner to prevent data corruption and maintain
data consistency. When multiple threads access shared resources concurrently
without proper synchronization, it can lead to issues such as data inconsistency, race
conditions, and deadlock.
The need for synchronization arises in scenarios where multiple threads are
accessing and modifying shared data concurrently. Without synchronization, these
threads can interfere with each other's operations and produce unpredictable results.
Here's an example to illustrate the need for synchronization:

class Counter {
private int count = 0;

public void increment() {


count++;
}

public int getCount() {


return count;
}
}

public class SynchronizationExample {


public static void main(String[] args) {
Counter counter = new Counter();

// Create two threads that increment the counter concurrently


Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

Thread thread2 = new Thread(() -> {


for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

thread1.start();
thread2.start();

// Wait for both threads to complete


try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

// Print the final count


System.out.println("Final Count: " + counter.getCount());
}
}

In this example, we have a Counter class with an increment() method that


increments a shared count variable. We create two threads (thread1 and thread2)
that concurrently call the increment() method of the Counter object. Each thread
increments the count variable 1000 times.
Without synchronization, the threads may interfere with each other's operations,
leading to unpredictable results. For example, the final count may not be 2000 as
expected due to race conditions.
To address this issue, we can use synchronization in Java. Synchronization can be
implemented using the synchronized keyword in Java.
Here's how synchronization can be implemented in the Counter class:

class Counter {
private int count = 0;

public synchronized void increment() {


count++;
}

public synchronized int getCount() {


return count;
}
}

By marking the increment() and getCount() methods as synchronized, we ensure


that only one thread can access these methods at a time, preventing concurrent
modification of the count variable and maintaining data consistency.
With proper synchronization, the program will produce the expected output of 2000
as the final count.

Q.Explain the role of synchronization in producer and consumer problem.


A. The producer-consumer problem is a classic synchronization problem in
computer science that involves two types of threads: producers and consumers.
Producers are responsible for producing data items and placing them into a shared
buffer or queue, while consumers retrieve and consume these data items from the
buffer.
The main challenge in the producer-consumer problem is to ensure that producers
and consumers operate correctly and efficiently without data corruption or deadlock.
Synchronization plays a crucial role in addressing this challenge by coordinating the
actions of producers and consumers and ensuring mutual exclusion and proper
access to the shared buffer.
Here's how synchronization helps in solving the producer-consumer problem:
1. Mutual Exclusion: Synchronization ensures that only one thread (either a
producer or a consumer) can access the shared buffer at a time. This
prevents multiple threads from simultaneously accessing or modifying the
buffer, which could lead to data corruption or inconsistency.
2. Producer-Consumer Coordination: Synchronization mechanisms such as
locks, semaphores, or monitors are used to coordinate the actions of
producers and consumers. For example, producers should wait if the buffer is
full, while consumers should wait if the buffer is empty. Synchronization
primitives help enforce these constraints and ensure that producers and
consumers operate in a coordinated manner.
3. Buffer Management: Synchronization is used to manage the buffer to prevent
overflows or underflows. Producers should wait if the buffer is full, and
consumers should wait if the buffer is empty. Synchronization primitives such
as condition variables or semaphores are often used to implement this
behavior.
4. Preventing Deadlocks: Synchronization mechanisms help prevent deadlock
situations where threads are waiting indefinitely for resources held by other
threads. By carefully coordinating the access to shared resources,
synchronization ensures that threads can make progress without getting
stuck in a deadlock.
Overall, synchronization is essential in solving the producer-consumer problem to
ensure correct and efficient coordination between producers and consumers, prevent
data corruption or inconsistency, and avoid deadlock situations. Various
synchronization techniques such as locks, semaphores, and condition variables are
used to achieve this coordination and mutual exclusion in practice.

Q.Write a Java program to illustrate synchronization using synchronization


methods.
A. class Counter {
private int count = 0;

// Synchronized method for incrementing count


public synchronized void increment() {
count++;
}

// Synchronized method for decrementing count


public synchronized void decrement() {
count--;
}

// Method to get current count


public int getCount() {
return count;
}
}

class IncrementThread extends Thread {


private Counter counter;

public IncrementThread(Counter counter) {


this.counter = counter;
}

public void run() {


for (int i = 0; i < 1000; i++) {
counter.increment();
}
}
}

class DecrementThread extends Thread {


private Counter counter;

public DecrementThread(Counter counter) {


this.counter = counter;
}

public void run() {


for (int i = 0; i < 1000; i++) {
counter.decrement();
}
}
}

public class SynchronizationExample {


public static void main(String[] args) {
Counter counter = new Counter();

IncrementThread incrementThread = new IncrementThread(counter);


DecrementThread decrementThread = new DecrementThread(counter);

incrementThread.start();
decrementThread.start();

// Wait for threads to finish


try {
incrementThread.join();
decrementThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

// Print the final count


System.out.println("Final Count: " + counter.getCount());
}
}

Q.Describe the various levels of access protections available for packages and
their implications with suitable program examples.
A.In Java, there are four levels of access protection provided by packages, which
control the visibility of classes, interfaces, constructors, and methods within the
same package or across different packages. These levels of access protection are:
1. Private: The private access modifier restricts access to the member to only
within the same class. It is the most restrictive access level.
2. Default (Package-private): If no access modifier is specified, the member has
default (package-private) access within the same package. It restricts access
to only within the same package.
3. Protected: The protected access modifier restricts access to the member to
within the same package or by subclasses (even if the subclass is in a
different package).
4. Public: The public access modifier provides unrestricted access to the
member from any other class or package.
Let's illustrate these access levels with suitable program examples:
Example 1: Private Access Modifier
package example;

class MyClass {
private int privateField;

private void privateMethod() {


// Method implementation
}
}

public class Main {


public static void main(String[] args) {
MyClass obj = new MyClass();
// obj.privateField is inaccessible because it is private
// obj.privateMethod() is inaccessible because it is private
}
}

In this example, privateField and privateMethod() are private members of the


MyClass class. They can only be accessed within the MyClass class itself and cannot
be accessed from outside the class, including from the Main class in a different
package.

Example 2: Default (Package-private) Access Modifier


package example;

class MyClass {
int defaultField; // Default (package-private) access

void defaultMethod() { // Default (package-private) access


// Method implementation
}
}

public class Main {


public static void main(String[] args) {
MyClass obj = new MyClass();
// obj.defaultField and obj.defaultMethod() can be accessed because they have
default access
}
}

In this example, defaultField and defaultMethod() are package-private members


of the MyClass class. They can be accessed from within the same package (example
package), but not from classes in other packages.
Example 3: Protected Access Modifier
package example1;

public class MyClass {


protected int protectedField;

protected void protectedMethod() {


// Method implementation
}
}

package example2;

import example1.MyClass;

public class Subclass extends MyClass {


public static void main(String[] args) {
Subclass obj = new Subclass();
// obj.protectedField and obj.protectedMethod() can be accessed because they
are inherited
}
}

In this example, protectedField and protectedMethod() are protected members of


the MyClass class. They can be accessed from within the same package (example1
package) and also by subclasses (e.g., Subclass) even if the subclass is in a
different package (example2 package).
Example 4: Public Access Modifier
package example;

public class MyClass {


public int publicField;

public void publicMethod() {


// Method implementation
}
}

public class Main {


public static void main(String[] args) {
MyClass obj = new MyClass();
// obj.publicField and obj.publicMethod() can be accessed because they have
public access
}
}
In this example, publicField and publicMethod() are public members of the
MyClass class. They can be accessed from any other class or package.

Q.Explain how variables in interfaces are used. Give examples


A.Variables in interfaces in Java are implicitly public, static, and final
(constants). They can be thought of as constants that can be accessed through the
interface name itself, similar to static variables in classes. Variables in interfaces are
commonly used to define constants or configuration values that are shared across
multiple classes.
Here's how variables in interfaces are used:

public interface MyInterface {


int MAX_VALUE = 100; // Implicitly public, static, and final
String DEFAULT_NAME = "John Doe"; // Another constant

// Other interface members (methods, nested interfaces, etc.) can also be


defined here
}

In this example:
● MAX_VALUE and DEFAULT_NAME are variables (constants) defined within the
MyInterface interface.
● They are implicitly public, static, and final, meaning they can be accessed
as MyInterface.MAX_VALUE and MyInterface.DEFAULT_NAME from any class
that implements the interface.
Here's an example demonstrating how variables in interfaces are used:

public class Main implements MyInterface {


public static void main(String[] args) {
System.out.println("Maximum value: " + MyInterface.MAX_VALUE);
System.out.println("Default name: " + MyInterface.DEFAULT_NAME);
}
}

Output:
yaml
Copy code
Maximum value: 100
Default name: John Doe

In this example, the Main class implements the MyInterface interface. It can access
the variables MAX_VALUE and DEFAULT_NAME defined in the interface directly using the
interface name (MyInterface). This allows for a centralized definition of constants
that can be easily accessed and shared across multiple classes.

Q.What are Interfaces? Explain Interfaces in java.


A.In Java, an interface is a reference type, similar to a class, that can contain only
constants, method signatures, default methods, static methods, and nested types. It
defines a contract or set of abstract methods that must be implemented by any
class that wants to adhere to the interface. In other words, an interface specifies
what a class must do, but it does not provide the implementation of those methods.
Interfaces in Java provide a way to achieve abstraction and multiple inheritance of
type. They allow classes from different hierarchies to share common method
signatures, enabling polymorphism and loose coupling.
Key features of interfaces in Java include:
1. Abstract Methods: Interfaces can contain method declarations without
method bodies (i.e., abstract methods), which must be implemented by any
class that implements the interface.
2. Constants: Interfaces can contain constant variables, which are implicitly
public, static, and final. These variables act as constants that can be
accessed through the interface name.
3. Default Methods: Java 8 introduced default methods, which allow interfaces
to provide default implementations for methods. Default methods are marked
with the default keyword and can be overridden by implementing classes.
4. Static Methods: Java 8 also introduced static methods in interfaces, which
can be defined with the static keyword. These methods can be called using
the interface name and cannot be overridden by implementing classes.
5. Nested Types: Interfaces can contain nested types such as other interfaces,
classes, or enums.
Here's an example of an interface in Java:

public interface MyInterface {


// Constant variables (implicitly public, static, and final)
int MAX_VALUE = 100;
String DEFAULT_NAME = "John Doe";

// Abstract method declaration


void myMethod();

// Default method with implementation


default void defaultMethod() {
System.out.println("Default method implementation");
}

// Static method with implementation


static void staticMethod() {
System.out.println("Static method implementation");
}

// Nested interface
interface NestedInterface {
void nestedMethod();
}
}

In this example:
● MyInterface is an interface containing constant variables (MAX_VALUE and
DEFAULT_NAME), an abstract method myMethod(), a default method
defaultMethod(), and a static method staticMethod().
● The interface also contains a nested interface NestedInterface with an
abstract method nestedMethod().
● Any class that implements the MyInterface interface must provide
implementations for the myMethod() method, and it may optionally override
the default methods if needed.
Q.With syntax explain the use of following methods in threads
i) isAlive( ) ii) Join( ) iii) wait() iv) notify() v) notifyAll()
A. Here's a brief explanation of each method with its syntax:
i) isAlive() method:
● This method checks whether a thread is still alive or has terminated.
● Syntax: boolean isAlive()
ii) join() method:
● This method waits for a thread to terminate. It causes the current thread to
pause its execution until the thread on which it's called completes its
execution.
● Syntax: void join()
iii) wait() method:
● This method causes the current thread to wait until another thread invokes the
notify() method or the notifyAll() method for this object.
● Syntax: void wait()
iv) notify() method:
● This method wakes up a single thread that is waiting on this object's monitor.
If multiple threads are waiting, only one of them is chosen to be awakened.
● Syntax: void notify()
v) notifyAll() method:
● This method wakes up all threads that are waiting on this object's monitor.
This causes all threads to become eligible for execution.
● Syntax: void notifyAll()

Note: The wait(), notify(), and notifyAll() methods must be called from within a
synchronized context, i.e., they should be called on an object while holding its lock.
Otherwise, an IllegalMonitorStateException will be thrown.

Q.What are enumerations? Explain the following methods with an example program.
i) values() and valueOf() ii) ordinal() iii) equals() iv) CompareTo()
A. Enumerations in Java are a special type of class that represents a group of
constants (enumerated values). Enumerations provide a way to define a fixed set of
named constants, which makes the code more readable, maintainable, and
error-prone.
Now, let's explain the methods associated with enumerations with examples:
i) values() and valueOf() methods:
● values(): This method returns an array containing all of the values of the
enumeration in the order they are declared.
● valueOf(): This method returns the enumeration constant with the specified
name.
● Example:
enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}

public class EnumExample {


public static void main(String[] args) {
// values() method example
Day[] days = Day.values();
for (Day day : days) {
System.out.println(day);
}
// valueOf() method example
Day monday = Day.valueOf("MONDAY");
System.out.println("Value of MONDAY: " + monday);
}
}

ii) ordinal() method:


● This method returns the ordinal position of the enumeration constant (its
position in the declaration, starting from zero).
● Example:
java
Copy code
enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}

public class EnumExample {


public static void main(String[] args) {
// ordinal() method example
System.out.println("Ordinal of MONDAY: " + Day.MONDAY.ordinal());
}
}

iii) equals() method:


● This method compares two enumeration constants for equality.
● Example:
java
Copy code
enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}

public class EnumExample {


public static void main(String[] args) {
Day day1 = Day.MONDAY;
Day day2 = Day.MONDAY;
Day day3 = Day.TUESDAY;

// equals() method example


System.out.println("day1 equals day2: " + day1.equals(day2)); // true
System.out.println("day1 equals day3: " + day1.equals(day3)); // false
}
}

iv) compareTo() method:


● This method compares two enumeration constants based on their ordinal
values.
● Example:
java
Copy code
enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}

public class EnumExample {


public static void main(String[] args) {
Day day1 = Day.MONDAY;
Day day2 = Day.TUESDAY;
Day day3 = Day.MONDAY;

// compareTo() method example


System.out.println("day1 compareTo day2: " + day1.compareTo(day2)); // -1
System.out.println("day1 compareTo day3: " + day1.compareTo(day3)); // 0
}
}

These methods provide various functionalities for working with enumerations in


Java, allowing you to manipulate and compare enumeration constants effectively.

Q. What is autoboxing and autounboxing? Write a Java program that demonstrates


how autoboxing and unboxing take place in expression in evaluation.
A. Autoboxing and autounboxing are features introduced in Java 5 (JDK 1.5) to
automatically convert between primitive data types and their corresponding wrapper
classes (e.g., int to Integer, double to Double, etc.) without requiring explicit casting
by the programmer.
● Autoboxing: It is the process of converting a primitive data type into its
corresponding wrapper class automatically. For example, converting int to
Integer, double to Double, etc.
● Autounboxing: It is the process of converting a wrapper class object back into
its corresponding primitive data type automatically. For example, converting
Integer to int, Double to double, etc.
Here's a Java program demonstrating how autoboxing and unboxing take place in
expressions:

public class AutoboxingUnboxingExample {


public static void main(String[] args) {
// Autoboxing: int to Integer
Integer num1 = 10; // Primitive int value is automatically boxed into Integer
object

// Autounboxing: Integer to int


int num2 = num1; // Integer object is automatically unboxed into int primitive
value

// Autoboxing: double to Double


Double value1 = 3.14; // Primitive double value is automatically boxed into
Double object

// Autounboxing: Double to double


double value2 = value1; // Double object is automatically unboxed into double
primitive value

// Using autoboxing and autounboxing in expressions


Integer result1 = num1 + 20; // Addition of Integer and int, autoboxing of int
to Integer
Double result2 = value1 + 2.5; // Addition of Double and double, autoboxing of
double to Double

// Printing results
System.out.println("Result 1: " + result1); // Output: 30
System.out.println("Result 2: " + result2); // Output: 5.64
}
}

In this example:
● Autoboxing occurs when assigning primitive values 10 and 3.14 to Integer
and Double objects, respectively.
● Autounboxing occurs when assigning num1 and value1 to primitive int and
double variables, respectively.
● Autoboxing and autounboxing also take place in expressions, such as addition
(num1 + 20 and value1 + 2.5), where int and double values are automatically
converted to Integer and Double objects for the operation and then
automatically unboxed back to primitive values for the result.

Q. What are type wrappers? Explain with a program example the character and
numeric type wrappers.
A. Type wrappers, also known as wrapper classes, are classes in Java that provide
an object representation of primitive data types. Each primitive data type in Java has
a corresponding wrapper class, which allows primitive data types to be used as
objects in Java programs. Wrapper classes are used to wrap primitive values and
provide methods to manipulate those values as objects.
There are two types of wrapper classes in Java:
​ Character wrapper classes: These classes are used to represent characters
(char).
● Character: Wrapper class for char.
​ Numeric wrapper classes: These classes are used to represent numeric data
types.
● Byte: Wrapper class for byte.
● Short: Wrapper class for short.
● Integer: Wrapper class for int.
● Long: Wrapper class for long.
● Float: Wrapper class for float.
● Double: Wrapper class for double.
Here's a program example demonstrating the character and numeric wrapper
classes:

public class WrapperExample {


public static void main(String[] args) {
// Character wrapper example
Character ch = 'A'; // Autoboxing: char to Character
System.out.println("Character: " + ch);

// Numeric wrapper examples


Integer intValue = 10; // Autoboxing: int to Integer
Double doubleValue = 3.14; // Autoboxing: double to Double

System.out.println("Integer value: " + intValue);


System.out.println("Double value: " + doubleValue);

// Unboxing: Integer to int


int intValueUnboxed = intValue;
System.out.println("Unboxed Integer value: " + intValueUnboxed);

// Unboxing: Double to double


double doubleValueUnboxed = doubleValue;
System.out.println("Unboxed Double value: " + doubleValueUnboxed);
}
}

Output:
Character: A
Integer value: 10
Double value: 3.14
Unboxed Integer value: 10
Unboxed Double value: 3.14

In this example:
● The Character wrapper class is used to wrap a char value 'A'.
● Numeric wrapper classes (Integer and Double) are used to wrap int and
double values, respectively.
● Autoboxing is used to automatically convert primitive values to wrapper
objects (intValue = 10 and doubleValue = 3.14).
● Unboxing is used to automatically convert wrapper objects to primitive values
(intValueUnboxed = intValue and doubleValueUnboxed = doubleValue).

You might also like