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

Oopj Paper Solution 2

Uploaded by

Vanuu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views

Oopj Paper Solution 2

Uploaded by

Vanuu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 45

OOPJ PAPER SOLUTION (19/01/2024)

Q.1
(a) List out basic concepts of OOP. Explain any one in detail.
The basic concepts of Object-Oriented Programming (OOP) in Java include:
1. **Classes and Objects**
2. **Inheritance**
3. **Polymorphism**
4. **Encapsulation**
5. **Abstraction**
Polymorphism
Polymorphism is the ability of an object to take on many forms. It allows one
interface to be used for a general class of actions. The specific action is
determined by the exact nature of the situation. In Java, polymorphism is
primarily achieved through method overloading and method overriding.
Method Overloading
Method overloading allows a class to have more than one method with the
same name, provided their parameter lists are different. This can make the
code more readable and intuitive.
Method Overriding
Method overriding allows a subclass to provide a specific implementation of a
method that is already defined in its superclass. This is used to achieve runtime
polymorphism.
Example:
// Base class
class Animal {
void makeSound() {
System.out.println("Some generic animal sound");
}
}

// Derived class
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Woof");
}
}

// Derived class
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("Meow");
}
}

// Main class to test polymorphism


public class TestPolymorphism {
public static void main(String[] args) {
Animal myAnimal;

myAnimal = new Dog();


myAnimal.makeSound(); // Output: Woof
myAnimal = new Cat();
myAnimal.makeSound(); // Output: Meow
}
}
In this example, `Animal` is the base class with a method `makeSound`. The
`Dog` and `Cat` classes override the `makeSound` method to provide specific
implementations. During runtime, the actual method that gets called is
determined by the type of object (`Dog` or `Cat`), demonstrating
polymorphism.

(b) Explain JVM in detail.


Java Virtual Machine (JVM)
The Java Virtual Machine (JVM) is a crucial component of the Java Runtime
Environment (JRE) responsible for executing Java programs. It provides an
environment where Java bytecode can be executed, regardless of the
underlying hardware and operating system.
Key Responsibilities of the JVM:
1. **Loading**: The JVM loads class files compiled by the Java compiler into
memory.
2. **Verification**: It ensures the bytecode is valid and doesn't violate Java's
security constraints.
3. **Execution**: The JVM executes the bytecode using an interpreter or a
Just-In-Time (JIT) compiler, which translates bytecode into native machine code
for performance optimization.
4. **Memory Management**: It manages memory allocation and deallocation
through the heap and stack, including garbage collection to free up memory
used by objects that are no longer needed.
5. **Runtime Environment**: Provides a runtime environment that includes
system libraries and other resources that Java programs need to run.
Architecture of the JVM:
1. **Class Loader**: Loads class files into the JVM.
2. **Runtime Data Areas**:
- **Method Area**: Stores class structures like metadata, the constant pool,
and method data.
- **Heap**: The runtime data area from which memory for all class
instances and arrays is allocated.
- **Java Stacks**: Each thread has its own Java stack, storing frames. A frame
holds local variables, partial results, and data for method invocation and
return.
- **Program Counter (PC) Register**: Each thread has its own PC register,
indicating the next instruction to execute.
- **Native Method Stack**: Contains information about native methods
used in the application.
3. **Execution Engine**:
- **Interpreter**: Executes bytecode instructions one at a time.
- **JIT Compiler**: Compiles bytecode into native machine code for
improved performance.
- **Garbage Collector**: Automatically deallocates memory by removing
objects that are no longer reachable in the application.
4. **Native Method Interface (JNI)**: Facilitates interaction between Java code
and native applications and libraries written in other languages like C or C++.
Example of JVM Workflow:
1. **Compilation**: Java source code is compiled into bytecode by the Java
compiler (`javac`).
2. **Class Loading**: The JVM class loader loads the bytecode into the JVM.
3. **Bytecode Verification**: The JVM verifies the bytecode for security
constraints.
4. **Execution**: The JVM interprets or compiles the bytecode to machine
code, which is then executed.
Benefits of JVM:
- **Platform Independence**: Write once, run anywhere (WORA) capability
because the JVM abstracts the underlying hardware and OS.
- **Memory Management**: Automatic memory management through
garbage collection.
- **Security**: Provides a secure execution environment by verifying bytecode
and enforcing access controls.
- **Performance**: Optimizations through JIT compilation improve execution
speed.
The JVM is fundamental to the execution of Java programs, ensuring they run
smoothly and efficiently across different platforms.

(c) Write a program in java to print Fibonacci series for n terms.


import java.util.Scanner;

public class FibonacciSeries {


public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the number of terms: ");
int n = scanner.nextInt();

int firstTerm = 0, secondTerm = 1;


System.out.print("Fibonacci Series: " + firstTerm + ", " + secondTerm);

for (int i = 3; i <= n; i++) {


int nextTerm = firstTerm + secondTerm;
System.out.print(", " + nextTerm);
firstTerm = secondTerm;
secondTerm = nextTerm;
}
scanner.close();
}
}
Explanation:
1. **Scanner**: Used to read the number of terms `n` from the user.
2. **Initial Terms**: The first two terms of the Fibonacci series are initialized to
`0` and `1`.
3. **Loop**: The `for` loop starts from the 3rd term and calculates each
subsequent term by summing the previous two terms.
4. **Print**: Each term is printed as it's calculated.
Usage:
- Compile the program using `javac FibonacciSeries.java`.
- Run the program using `java FibonacciSeries`.
- Enter the desired number of terms when prompted.

(c) Write a program in java to find out minimum from any ten
numbers using command line argument.
public class FindMinimum {
public static void main(String[] args) {
if (args.length != 10) {
System.out.println("Please provide exactly 10 numbers as command line
arguments.");
return;
}

int min = Integer.parseInt(args[0]);


for (int i = 1; i < args.length; i++) {
int num = Integer.parseInt(args[i]);
if (num < min) {
min = num;
}
}

System.out.println("The minimum number is: " + min);


}
}
Explanation:
1. **Command-line Arguments**: The program expects exactly 10 numbers as
command-line arguments.
2. **Validation**: Checks if exactly 10 arguments are provided.
3. **Initial Minimum**: Initializes the minimum value with the first argument.
4. **Loop**: Iterates through the remaining arguments, updating the
minimum value if a smaller number is found.
5. **Output**: Prints the minimum number.
Usage:
1. **Compile** the program using `javac FindMinimum.java`.
2. **Run** the program with ten numbers as arguments:
```sh
java FindMinimum 45 67 23 89 12 34 56 78 90 11
This will output:
The minimum number is: 11

Q.2
(a) What is wrapper class? Explain with example
In Java, a wrapper class is a class that encapsulates a primitive data type within
an object. This allows primitive data types to be used as objects, providing the
benefits of object-oriented programming, such as the ability to use methods
and the compatibility with Java's collection framework which can only hold
objects.
Primitive Types and Their Corresponding Wrapper Classes:
- **int** -> **Integer**
- **char** -> **Character**
- **boolean** -> **Boolean**
- **byte** -> **Byte**
- **short** -> **Short**
- **long** -> **Long**
- **float** -> **Float**
- **double** -> **Double**
Example:
Here's a simple example demonstrating the use of a wrapper class:
public class WrapperClassExample {
public static void main(String[] args) {
// Creating wrapper class objects
Integer intObject = Integer.valueOf(10); // Boxing: Converting int to Integer
int primitiveInt = intObject.intValue(); // Unboxing: Converting Integer to
int

// Autoboxing and Unboxing


Integer autoBoxedInt = 20; // Automatically boxed to Integer
int autoUnboxedInt = autoBoxedInt; // Automatically unboxed to int

// Using a wrapper class in a collection


ArrayList<Integer> intList = new ArrayList<>();
intList.add(intObject);
intList.add(autoBoxedInt);

// Displaying the values


System.out.println("Integer object: " + intObject);
System.out.println("Primitive int from Integer object: " + primitiveInt);
System.out.println("Autoboxed Integer: " + autoBoxedInt);
System.out.println("Auto unboxed int: " + autoUnboxedInt);
System.out.println("ArrayList of Integers: " + intList);
}
}
Explanation:
- **Boxing**: Manually converting a primitive type to its corresponding
wrapper object using methods like `Integer.valueOf(10)`.
- **Unboxing**: Manually converting a wrapper object to its corresponding
primitive type using methods like `intObject.intValue()`.
- **Autoboxing**: The automatic conversion of a primitive type to its
corresponding wrapper object (e.g., `Integer autoBoxedInt = 20`).
- **Auto-unboxing**: The automatic conversion of a wrapper object to its
corresponding primitive type (e.g., `int autoUnboxedInt = autoBoxedInt`).
- **Collections**: Demonstrates how wrapper objects can be used in
collections like `ArrayList`, which can only store objects.
Wrapper classes provide a way to treat primitives as objects, which is essential
for working with Java's collection framework and taking advantage of object-
oriented programming features.

(b) List out different features of java. Explain any two.

Java offers a wide range of features, but here are some key ones:
1. Simple: Java was designed to be easy to learn and use. It has a clean
syntax, automatic memory management, and clear documentation.
2. Object-Oriented: Java follows an object-oriented programming
paradigm, which promotes modularity, reusability, and extensibility.
Everything in Java is an object, allowing for better organization of code.
3. Platform Independence: Java programs are compiled into bytecode,
which can be executed on any platform with the help of the Java Virtual
Machine (JVM). This "write once, run anywhere" capability makes Java
platform-independent.
4. Secure: Java provides a robust security model with features like
bytecode verification, class loading, and runtime permissions to protect
systems from malicious code.
5. Multithreading: Java supports multithreading, allowing multiple threads
of execution to run concurrently within a single program. This feature is
essential for developing scalable and responsive applications.
6. Distributed: Java supports distributed computing by providing APIs for
network communication, remote method invocation (RMI), and web
services, enabling the development of distributed applications.
7. Dynamic: Java supports dynamic memory allocation and dynamic
linking, allowing for flexibility in memory management and runtime
loading of classes.
8. High Performance: Java's Just-In-Time (JIT) compiler optimizes bytecode
into native machine code at runtime, leading to high performance and
efficient execution.

(c) What is method overload? Explain with example.


Method overloading in Java is the ability to define multiple methods in the
same class with the same name but with different parameter lists. This allows
methods to perform similar tasks with different inputs.

Example:

public class Calculator {

// Method to add two integers

public int add(int a, int b) {

return a + b;

}
// Method to add three integers

public int add(int a, int b, int c) {

return a + b + c;

// Method to add two doubles

public double add(double a, double b) {

return a + b;

In this example, the `Calculator` class has three `add` methods:

- The first `add` method takes two integers as parameters.

- The second `add` method takes three integers as parameters.

- The third `add` method takes two doubles as parameters.

All three methods have the same name (`add`), but they differ in the number
or type of parameters they accept. This is method overloading. When you call
the `add` method with different parameter lists, Java determines which version
of the method to execute based on the arguments provided.

Q.2
(a) Explain Garbage collection in java.
Garbage collection in Java is the process by which the Java Virtual Machine
(JVM) automatically deallocates memory used by objects that are no longer
reachable or needed by the program. It's a mechanism for automatic memory
management, ensuring efficient memory usage and preventing memory leaks.
Key Points:

1. **Automatic Memory Management**: Java's garbage collector


automatically identifies and removes objects that are no longer in use, freeing
up memory for reuse.

2. **Mark and Sweep Algorithm**: The most common garbage collection


algorithm used by Java is the mark and sweep algorithm. It works by marking
objects that are still reachable (reachable from the program's execution stack
or other reachable objects) and then sweeping through memory to deallocate
memory occupied by objects that are not marked.

3. **Finalization**: Before an object is reclaimed by the garbage collector, its


`finalize()` method is invoked (if overridden). This allows objects to perform
cleanup tasks before being garbage collected.

4. **Tuning and Configuration**: Java provides mechanisms to configure and


tune the garbage collector according to the specific requirements of the
application, such as heap size, garbage collection algorithm, and frequency of
garbage collection cycles.

5. **Low Pause Time**: Modern garbage collectors in Java, such as the G1


garbage collector, aim to minimize pause times by performing garbage
collection incrementally or concurrently with the execution of the program.
This helps in maintaining responsiveness in applications.

Benefits:

- **Prevents Memory Leaks**: Garbage collection prevents memory leaks by


automatically reclaiming memory occupied by objects that are no longer
needed.

- **Simplifies Memory Management**: Developers don't need to manually


allocate or deallocate memory, reducing the risk of memory-related errors.

- **Improves Productivity**: Automatic memory management allows


developers to focus on writing application logic rather than managing memory.

Garbage collection is a fundamental feature of Java that helps ensure


robustness, stability, and performance in Java applications.
(b) Explain final keyword with example.
In Java, the `final` keyword is used to declare constants, restrict inheritance,
and prevent method overriding.

Example 1: Final Variables (Constants)

public class Circle {

// Final variables (constants)

final double PI = 3.14159;

final int radius;

// Constructor to initialize final variable

public Circle(int r) {

radius = r;

// Method to calculate area

public double calculateArea() {

return PI * radius * radius;

In this example, `PI` is a final variable (constant) whose value cannot be


changed. `radius` is also a final variable, but its value is set in the constructor
and cannot be changed after initialization.

Example 2: Final Methods

public class Parent {


// Final method

public final void display() {

System.out.println("This is the parent's display method");

public class Child extends Parent {

// Error: Cannot override final method

// public void display() {

// System.out.println("This is the child's display method");

// }

In this example, `display()` method in the `Parent` class is declared as final,


preventing any subclass from overriding it.

Example 3: Final Classes

final class FinalClass {

// Class implementation

// Error: Cannot inherit from final class

// class Subclass extends FinalClass { }

In this example, `FinalClass` is declared as final, preventing any subclass from


inheriting it.
Summary:

- **Final variables**: Constants whose values cannot be changed.

- **Final methods**: Cannot be overridden by subclasses.

- **Final classes**: Cannot be subclassed.

The `final` keyword ensures immutability, security, and design integrity in Java
programs.

(c) What is constructor? Explain parameterized constructor with


example.
In Java, a constructor is a special type of method that is used to initialize
objects. It has the same name as the class and does not have a return type.
Constructors are invoked automatically when an object is created using the
`new` keyword.
Parameterized Constructor:
A parameterized constructor is a constructor with parameters, allowing you to
initialize object properties with specific values during object creation.
Example:
public class Person {
private String name;
private int age;

// Parameterized constructor
public Person(String name, int age) {
this.name = name;
this.age = age;
}

// Method to display person's information


public void displayInfo() {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
}

public static void main(String[] args) {


// Creating object using parameterized constructor
Person person1 = new Person("John", 30);
person1.displayInfo();

// Creating another object


Person person2 = new Person("Alice", 25);
person2.displayInfo();
}
}
In this example:
- `Person` class has a parameterized constructor that takes two parameters:
`name` and `age`.
- Inside the constructor, the `name` and `age` properties of the object are
initialized with the values passed as parameters.
- Two `Person` objects (`person1` and `person2`) are created using the
parameterized constructor with different values.
- The `displayInfo()` method is used to display the information of each person
object.
When you run this program, it will output the name and age of each person
object:
Name: John
Age: 30
Name: Alice
Age: 25
Parameterized constructors are useful for initializing object properties with
specific values at the time of object creation, providing flexibility and
customization in object initialization.

Q. 3
(a) Explain super keyword with example.
In Java, the `super` keyword is used to refer to the superclass (parent class) of a
subclass (child class). It can be used to access superclass methods,
constructors, and variables.
Example:
// Parent class
class Vehicle {
String brand;

// Constructor
Vehicle(String brand) {
this.brand = brand;
}

// Method
void displayInfo() {
System.out.println("Brand: " + brand);
}
}

// Child class
class Car extends Vehicle {
int year;

// Constructor
Car(String brand, int year) {
super(brand); // Calls the constructor of the superclass
this.year = year;
}

// Method overriding
@Override
void displayInfo() {
super.displayInfo(); // Calls the method of the superclass
System.out.println("Year: " + year);
}
}

public class Main {


public static void main(String[] args) {
Car myCar = new Car("Toyota", 2022);
myCar.displayInfo();
}
}
In this example:
- `Vehicle` is the superclass with a constructor and a method `displayInfo`.
- `Car` is the subclass of `Vehicle` with an additional property `year`.
- Inside the `Car` constructor, `super(brand)` calls the constructor of the
superclass `Vehicle`, passing the `brand` parameter.
- Inside the `displayInfo` method of `Car`, `super.displayInfo()` calls the
`displayInfo` method of the superclass `Vehicle`.
- When you run this program, it will output:
Brand: Toyota
Year: 2022
The `super` keyword is useful for accessing superclass members and
constructors from a subclass, enabling code reuse and facilitating method
overriding.

(b) List out different types of inheritance. Explain multilevel


inheritance.
In Java, inheritance allows one class to inherit properties and behavior from
another class. There are several types of inheritance:
1. **Single Inheritance**: A subclass inherits from only one superclass.
2. **Multilevel Inheritance**: A subclass inherits from another subclass,
creating a chain of inheritance.
3. **Hierarchical Inheritance**: Multiple subclasses inherit from the same
superclass.
4. **Multiple Inheritance** (not directly supported in Java): A subclass inherits
from more than one superclass.
Multilevel Inheritance:
In multilevel inheritance, a subclass inherits from another subclass, creating a
chain of inheritance. This means a class acts as both a superclass and a
subclass.
Example:
// Superclass
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}

// Subclass inheriting from superclass


class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}

// Subclass inheriting from subclass (Multilevel Inheritance)


class Labrador extends Dog {
void color() {
System.out.println("Labrador is brown in color");
}
}

public class Main {


public static void main(String[] args) {
Labrador labrador = new Labrador();
labrador.eat(); // Inherited from Animal class
labrador.bark(); // Inherited from Dog class
labrador.color(); // Defined in Labrador class
}
}
In this example:
- `Animal` is the superclass with a method `eat`.
- `Dog` is a subclass of `Animal` with an additional method `bark`.
- `Labrador` is a subclass of `Dog` with an additional method `color`.
- `Labrador` inherits the `eat` method from `Animal` and the `bark` method
from `Dog`.
- When you run this program, it will output:
Animal is eating
Dog is barking
Labrador is brown in color
Multilevel inheritance provides a way to create a hierarchy of classes with
increasing specialization, allowing for code reuse and better organization of
class relationships. However, it can lead to complexity and tight coupling
between classes if not used carefully.

(c) What is interface? Explain multiple inheritance with example.


In Java, an interface is a reference type similar to a class that can contain only
abstract methods, default methods, static methods, constant variables, and
nested types. It defines a contract that implementing classes must follow,
specifying the methods that they must implement.
Multiple Inheritance with Interfaces:
Java supports multiple inheritance through interfaces. A class can implement
multiple interfaces, allowing it to inherit abstract methods from all of them.
Example:
// Interface 1
interface Flyable {
void fly();
}

// Interface 2
interface Swimmable {
void swim();
}

// Class implementing multiple interfaces


class Bird implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("Bird is flying");
}

@Override
public void swim() {
System.out.println("Bird is swimming");
}
}

public class Main {


public static void main(String[] args) {
Bird bird = new Bird();
bird.fly();
bird.swim();
}
}
In this example:
- `Flyable` is an interface with an abstract method `fly`.
- `Swimmable` is another interface with an abstract method `swim`.
- `Bird` class implements both `Flyable` and `Swimmable` interfaces, providing
concrete implementations for their abstract methods.
- When you run this program, it will output:
Bird is flying
Bird is swimming
In this way, a class can inherit behavior from multiple interfaces, allowing for
flexible and modular design while avoiding the complexities and ambiguities
associated with multiple inheritance of classes.

Q. 3
(a) Explain static keyword with example.
In Java, the `static` keyword is used to declare members (variables and
methods) that belong to the class itself rather than to instances of the class.
These members are shared among all instances of the class and can be
accessed directly through the class name without creating an object of the
class.
Example:
public class Counter {
// Static variable
static int count = 0;

// Static method
static void increment() {
count++;
}

// Static method
static void displayCount() {
System.out.println("Count: " + count);
}

public static void main(String[] args) {


Counter.increment(); // Increment count
Counter.displayCount(); // Display count

Counter.increment(); // Increment count again


Counter.displayCount(); // Display count again
}
}
In this example:
- `count` is a static variable, shared among all instances of the `Counter` class.
- `increment()` and `displayCount()` are static methods, which can be called
directly through the class name.
- When you run this program, it will output:
Count: 1
Count: 2
Static members are commonly used for constants, utility methods, or variables
that need to be shared across instances of the class. They are loaded into
memory when the class is loaded and are accessible without creating an
instance of the class.

(b) Explain different access controls in Java.


In Java, there are four access control modifiers that define the visibility and
accessibility of classes, variables, methods, and constructors within a program:
1. **Public**: Accessible from anywhere, both within and outside the package.
2. **Protected**: Accessible within the same package and by subclasses (even
if they are in a different package).
3. **Default (No modifier)**: Accessible within the same package only. If no
access control modifier is specified, it defaults to package-private.
4. **Private**: Accessible within the same class only.
Example:
// Public access control
public class PublicClass {
public void publicMethod() {
System.out.println("Public method");
}
}

// Protected access control


class ProtectedClass {
protected void protectedMethod() {
System.out.println("Protected method");
}
}

// Default (package-private) access control


class DefaultClass {
void defaultMethod() {
System.out.println("Default method");
}
}

// Private access control


class PrivateClass {
private void privateMethod() {
System.out.println("Private method");
}
}
In this example:
- `PublicClass` is accessible from anywhere.
- `ProtectedClass` is accessible within the same package and by subclasses.
- `DefaultClass` is accessible within the same package only.
- `PrivateClass` is accessible within the same class only.
Access control modifiers help in encapsulation, ensuring that classes and
members are visible and accessible according to the desired level of
encapsulation and security.

(c) What is package? Write steps to create a package and give


example of it.
In Java, a package is a way of organizing classes into namespaces or modules to
avoid naming conflicts and provide a hierarchical structure to the codebase.
Steps to create a package:
1. **Choose a Package Name**: Decide on a name for your package. Package
names usually follow the reverse domain name convention (e.g.,
`com.example.package`).
2. **Create a Directory Structure**: Create a directory structure that reflects
the package name. Each subdirectory represents a component of the package
name.
3. **Place Java Files in the Directory Structure**: Place your Java files (*.java)
inside the appropriate directory according to their package structure.
4. **Add Package Declaration**: Add a `package` declaration at the beginning
of each Java file to specify the package to which the class belongs.
5. **Compile Java Files**: Compile the Java files using the `javac` command,
ensuring that the class files are generated in the correct directory structure.
Example:
Suppose you want to create a package named `com.example.util` containing a
class named `StringUtils` that provides utility methods for string manipulation.
Directory Structure:
project/
└── src/
└── com/
└── example/
└── util/
└── StringUtils.java
StringUtils.java:
package com.example.util;

public class StringUtils {


public static boolean isEmpty(String str) {
return str == null || str.isEmpty();
}
}
In this example:
- The `StringUtils` class is placed in the `com.example.util` package.
- The directory structure mirrors the package structure.
- The `package` declaration specifies the package to which the `StringUtils` class
belongs.
- After compiling, the class file will be located in the corresponding directory
structure under the `bin` or `target` directory.

Q. 4
(a) Explain thread priorities with suitable example.
In Java, thread priorities are used to indicate the importance or urgency of a
thread's execution relative to other threads. Threads with higher priority are
scheduled to run before threads with lower priority. Java provides 10 priority
levels, ranging from 1 (lowest) to 10 (highest), with the default priority being 5.
Example:
public class PriorityExample {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable(), "Thread 1");
Thread t2 = new Thread(new MyRunnable(), "Thread 2");

// Set priorities for threads


t1.setPriority(Thread.MIN_PRIORITY); // Set minimum priority
t2.setPriority(Thread.MAX_PRIORITY); // Set maximum priority

// Start threads
t1.start();
t2.start();
}

static class MyRunnable implements Runnable {


public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
In this example:
- Two threads (`t1` and `t2`) are created and started.
- `t1` is set to the minimum priority, and `t2` is set to the maximum priority.
- Both threads execute a simple task of printing numbers from 1 to 5 with a
delay of 1 second between each number.
- Since `t2` has a higher priority, it is expected to complete its execution before
`t1`.
- Output may vary, but you'll likely see `Thread 2` completing its execution
before `Thread 1`.
Thread priorities are used to influence the thread scheduler's decisions about
when to switch between threads, but they are not guaranteed to have a
significant impact on program execution, as it ultimately depends on the
underlying operating system and JVM implementation.

(b) What is Thread? Explain Thread life cycle.

In Java, a thread is the smallest unit of execution within a process. It represents


a single sequential flow of control within a program. Threads allow concurrent
execution, enabling programs to perform multiple tasks simultaneously.
Thread Life Cycle:

1. New: A thread is in the new state when it's created but has not yet
started.
2. Runnable: A thread is in the runnable state when it's ready to run and
waiting for the processor to execute it.
3. Running: A thread is in the running state when the processor is actively
executing its task.
4. Blocked/Waiting: A thread is in the blocked or waiting state when it's
temporarily inactive, waiting for a resource or condition to become
available.
5. Timed Waiting: A thread is in the timed waiting state when it's
temporarily inactive for a specified amount of time.
6. Terminated: A thread is in the terminated state when it has completed
execution or terminated due to an exception.

(c) Write a program in java that create the multiple threads by


implementing the Thread class.
class MyThread extends Thread {
private String threadName;

MyThread(String name) {
threadName = name;
}

public void run() {


for (int i = 1; i <= 5; i++) {
System.out.println(threadName + ": " + i);
try {
Thread.sleep(500); // Sleep for 500 milliseconds
} catch (InterruptedException e) {
System.out.println(e);
}
}
System.out.println(threadName + " is done.");
}

public static void main(String[] args) {


MyThread t1 = new MyThread("Thread 1");
MyThread t2 = new MyThread("Thread 2");
MyThread t3 = new MyThread("Thread 3");

// Start the threads


t1.start();
t2.start();
t3.start();
}
}
Explanation:
- **Class `MyThread`**: Extends the `Thread` class and overrides the `run`
method.
- **Constructor**: Takes a `name` parameter to identify the thread.
- **`run` Method**: Prints numbers from 1 to 5, with a 500-millisecond sleep
between prints.
- **`main` Method**: Creates and starts three instances of `MyThread`.
When you run this program, it will output the counts from each thread,
demonstrating concurrent execution:
Thread 1: 1
Thread 2: 1
Thread 3: 1
Thread 1: 2
Thread 2: 2
Thread 3: 2
...
Thread 1 is done.
Thread 2 is done.
Thread 3 is done.

Q. 4
(a) List four different inbuilt exceptions. Explain any one inbuilt
exception.
Four different inbuilt exceptions in Java are:
1. **NullPointerException**: Occurs when you try to access or invoke methods
on an object reference that is `null`.
2. **ArithmeticException**: Occurs when an arithmetic operation is attempted
with inappropriate operands.
3. **ArrayIndexOutOfBoundsException**: Occurs when you try to access an
array element at an invalid index.
4. **FileNotFoundException**: Occurs when an attempt to open the file
specified by a filename has failed.
Explanation of NullPointerException:
The `NullPointerException` is one of the most common exceptions in Java, and
it occurs when you try to access or invoke methods on an object reference that
is `null`, meaning the object has not been instantiated.
Example:
public class NullPointerExceptionExample {
public static void main(String[] args) {
String str = null;
// This line will throw a NullPointerException
int length = str.length();
}
}
In this example, `str` is assigned `null`, and attempting to access its `length`
property (`str.length()`) results in a `NullPointerException` because you cannot
invoke methods on a `null` object reference.
Handling `NullPointerException` involves ensuring that object references are
properly initialized before accessing their properties or invoking their methods,
or using conditional checks to handle `null` values appropriately.

(b) Explain multiple catch with suitable example.


In Java, you can use multiple `catch` blocks to handle different types of
exceptions separately within a single try-catch statement. This allows you to
handle each type of exception differently based on its specific nature.
Example:
public class MultipleCatchExample {
public static void main(String[] args) {
try {
int[] arr = new int[3];
arr[3] = 10 / 0; // ArithmeticException
String str = null;
int length = str.length(); // NullPointerException
} catch (ArithmeticException e) {
System.out.println("ArithmeticException occurred: " + e.getMessage());
} catch (NullPointerException e) {
System.out.println("NullPointerException occurred: " + e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException occurred: " +
e.getMessage());
} catch (Exception e) {
System.out.println("Exception occurred: " + e.getMessage());
}
}
}
In this example:
- The code inside the try block attempts two operations that may throw
exceptions: dividing by zero (ArithmeticException) and accessing the length of a
null string (NullPointerException).
- Each type of exception is caught separately using a separate catch block.
- If an ArithmeticException occurs, the first catch block handles it.
- If a NullPointerException occurs, the second catch block handles it.
- If an ArrayIndexOutOfBoundsException occurs, the third catch block handles
it.
- If any other type of exception occurs, the last catch block (catching
`Exception`) handles it.
Using multiple catch blocks allows you to handle different types of exceptions
gracefully, providing specific error messages or actions tailored to each type of
exception.

(c) What is Exception? Write a program that show the use of


Arithmetic Exception.
In Java, an exception is an event that disrupts the normal flow of a program's
execution. It occurs when an error or exceptional condition arises during the
execution of a program. Exceptions can be thrown by the Java Virtual Machine
(JVM) or by the code itself using the `throw` keyword.
Example demonstrating ArithmeticException:
public class ArithmeticExceptionExample {
public static void main(String[] args) {
try {
int result = divide(10, 0); // Division by zero will cause
ArithmeticException
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("ArithmeticException occurred: " + e.getMessage());
}
}

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


return dividend / divisor; // Division operation
}
}
In this example:
- The `divide` method performs a division operation (`dividend / divisor`).
- In the `main` method, the `divide` method is called with parameters `10` and
`0`, causing an attempt to divide by zero.
- Division by zero results in an `ArithmeticException`, which is caught by the
catch block.
- The catch block handles the `ArithmeticException` by printing an error
message.

When you run this program, it will output:


ArithmeticException occurred: / by zero
This demonstrates how an `ArithmeticException` is thrown and caught in Java
when attempting to divide by zero.
Q.5
(a) Explain ArrayIndexOutOfBound Exception in Java with example.
In Java, an ArrayIndexOutOfBoundsException is thrown when attempting to
access an array element at an invalid index. This typically occurs when trying to
access an index that is either negative or greater than or equal to the length of
the array.
Example:
public class ArrayIndexOutOfBoundsExceptionExample {
public static void main(String[] args) {
try {
int[] arr = new int[3];
arr[3] = 10; // Index 3 is out of bounds for the array
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException occurred: " +
e.getMessage());
}
}
}
In this example:
- An array `arr` of size 3 is created.
- An attempt is made to assign a value to `arr[3]`, which is beyond the bounds
of the array (valid indices are 0, 1, and 2).
- This results in an ArrayIndexOutOfBoundsException.
- The catch block catches the exception and prints an error message.
When you run this program, it will output:
ArrayIndexOutOfBoundsException occurred: Index 3 out of bounds for length 3
This demonstrates how an ArrayIndexOutOfBoundsException is thrown and
caught in Java when trying to access an array element at an invalid index.
(b) Explain basics of stream classes.
In Java, stream classes provide a mechanism for performing input and output
operations. Streams are a sequence of data that can be read from or written to,
and they provide a way to handle data in a continuous flow. There are two
main types of stream classes in Java: input streams and output streams.
1. **Input Streams**: Input streams are used to read data from a source, such
as a file, network connection, or keyboard input. Examples of input stream
classes include `InputStream`, `FileInputStream`, `ObjectInputStream`, etc.
2. **Output Streams**: Output streams are used to write data to a destination,
such as a file, network connection, or console output. Examples of output
stream classes include `OutputStream`, `FileOutputStream`,
`ObjectOutputStream`, etc.
Key Points:
- **Byte Streams vs. Character Streams**: Streams can operate on byte-level
data (byte streams) or character-level data (character streams). Byte streams
are used for binary data, while character streams are used for text data.
- **Sequential Processing**: Streams are typically processed sequentially,
meaning data is read or written one byte or character at a time.
- **Buffering**: Streams often use buffering to improve performance by
reading or writing data in larger chunks rather than individual bytes or
characters.
- **Automatic Resource Management (ARM)**: Java 7 introduced the try-with-
resources statement, which automatically closes streams after they are no
longer needed, helping to prevent resource leaks.
Example:
Reading from a file using FileInputStream:
import java.io.*;

public class StreamExample {


public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("input.txt")) {
int byteRead;
while ((byteRead = fis.read()) != -1) {
System.out.print((char) byteRead); // Convert byte to character and
print
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
In this example:
- We use FileInputStream to read bytes from the file "input.txt".
- We read bytes one at a time using the `read()` method and print each byte as
a character.
- We use try-with-resources to ensure that the FileInputStream is automatically
closed after use.
Understanding stream classes is essential for performing input and output
operations in Java, whether it's reading from a file, writing to a network
connection, or interacting with other data sources.

(c) Write a java program to create a text file and perform read
operation on the text file.
Below is a short Java program to create a text file and perform a read operation
on the text file:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class FileReadWriteExample {
public static void main(String[] args) {
String fileName = "example.txt";

// Write data to the text file


try (PrintWriter writer = new PrintWriter(new FileWriter(fileName))) {
writer.println("Hello, this is a text file.");
writer.println("This is the second line.");
} catch (IOException e) {
e.printStackTrace();
}

// Read data from the text file


try (BufferedReader reader = new BufferedReader(new
FileReader(fileName))) {
String line;
System.out.println("Contents of the text file:");
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
In this program:
- We first create a text file named "example.txt" and write some text into it
using a PrintWriter.
- Then, we read the contents of the text file using a BufferedReader and print
each line to the console.
When you run this program, it will output:
Contents of the text file:
Hello, this is a text file.
This is the second line.
This program demonstrates basic file I/O operations in Java, including creating
a text file, writing to it, and reading from it.

Q.5
(a) Explain Divide by Zero Exception in Java with example.
In Java, a Divide by Zero Exception, formally known as ArithmeticException,
occurs when attempting to divide an integer or floating-point number by zero.
This operation is not mathematically defined and results in an error condition.
Example:
public class DivideByZeroExample {
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("ArithmeticException occurred: " + e.getMessage());
}
}

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


return dividend / divisor; // Division operation
}
}
In this example:
- The `divide` method performs a division operation (`dividend / divisor`).
- In the `main` method, the `divide` method is called with parameters `10` and
`0`, causing an attempt to divide by zero.
- Division by zero results in an ArithmeticException.
- The catch block catches the ArithmeticException and prints an error message.
When you run this program, it will output:
ArithmeticException occurred: / by zero
This demonstrates how a Divide by Zero Exception (ArithmeticException) is
thrown and caught in Java when attempting to divide by zero.

(b) Explain java I/O process.


In Java, Input/Output (I/O) is the process of transferring data between a
program and external sources such as files, network connections, or user input
devices. Java provides a rich set of classes and APIs for performing I/O
operations efficiently and effectively.
Basic Java I/O Process:
1. **Open a Stream**: First, you need to open a stream to the data source or
destination. There are different types of streams for reading and writing data,
such as FileInputStream/FileOutputStream for reading/writing files,
SocketInputStream/SocketOutputStream for network I/O, etc.
2. **Read or Write Data**: Once the stream is opened, you can read data from
or write data to the stream using appropriate methods provided by the stream
classes. For example, `read()` method to read bytes, `write()` method to write
bytes, `readLine()` method to read a line of text, etc.
3. **Close the Stream**: After reading or writing data, it's important to close
the stream to release any system resources associated with it and to ensure
data integrity. Closing a stream is done using the `close()` method.
Example:
Reading from a file and printing its contents:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class FileReadExample {


public static void main(String[] args) {
String fileName = "example.txt";

try (BufferedReader reader = new BufferedReader(new


FileReader(fileName))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
In this example:
- We open a BufferedReader to read from the file "example.txt".
- We read each line from the file using the `readLine()` method.
- We print each line to the console.
- After reading is done, the BufferedReader is automatically closed by using try-
with-resources.
Understanding the Java I/O process is crucial for interacting with external data
sources efficiently and safely in Java applications.

(c) Write a java program to display the content of a text file and
perform append operation on the text file.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileAppendExample {


public static void main(String[] args) {
String fileName = "example.txt";

// Display content of the text file


displayFileContent(fileName);

// Append operation on the text file


appendToFile(fileName, "This line is appended.");

// Display content of the text file after append operation


displayFileContent(fileName);
}

// Method to display content of the text file


private static void displayFileContent(String fileName) {
try (BufferedReader reader = new BufferedReader(new
FileReader(fileName))) {
String line;
System.out.println("Contents of the text file:");
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}

// Method to perform append operation on the text file


private static void appendToFile(String fileName, String content) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName,
true))) {
writer.newLine(); // Move to the next line
writer.write(content); // Write content to the file
} catch (IOException e) {
e.printStackTrace();
}
}
}
In this program:
- We first display the content of the text file "example.txt".
- Then, we perform an append operation by adding a new line to the end of the
file with the text "This line is appended."
- Finally, we display the content of the text file again to see the changes after
the append operation.
Ensure that the file "example.txt" exists in the same directory as the Java
program, or provide the correct path to the file.

You might also like