Java Question Bank Ans
Java Question Bank Ans
Java Question Bank Ans
2 Marks:
• final: In Java, the final keyword is used to declare constants. When a variable is declared as final, it
cannot be modified, meaning its value cannot change once assigned. It can also be used for methods
and classes:
o Final variable: Value cannot be reassigned.
o Final method: Cannot be overridden by subclasses.
o Final class: Cannot be subclassed.
• finalize: This is a method in Java used to perform cleanup operations before an object is garbage
collected. The finalize method is called by the garbage collector on an object when it determines that
there are no more references to the object. This method is now deprecated since Java 9.
An Exception in Java is an event that disrupts the normal flow of a program's instructions. It represents an error
or unexpected condition that a program encounters during execution. Exceptions are used to handle runtime
errors, allowing the program to continue running or terminate gracefully.
• Exception: Represents conditions that a program can handle, such as divide-by-zero or file-not-found
situations. Exceptions are recoverable and are subclasses of the Exception class.
• Error: Represents serious issues that occur during the execution of a program, usually related to the
environment in which the application is running, like OutOfMemoryError or StackOverflowError.
Errors are not intended to be caught by typical application code and are subclasses of the Error class.
5. Define Multithreading.
Multithreading in Java is a process of executing multiple threads simultaneously. A thread is a lightweight
process, and multithreading allows concurrent execution of two or more parts of a program for maximum
utilization of CPU. Each thread runs independently, but they can share resources.
Every thread in Java has a priority, which helps determine the order in which threads are scheduled for
execution. Thread priorities are integers ranging from MIN_PRIORITY (value 1) to MAX_PRIORITY (value
10), with the default priority being NORM_PRIORITY (value 5). Higher priority threads are more likely to be
executed before lower priority ones, though this is ultimately determined by the thread scheduler, which is OS-
dependent.
The scope of a variable defines where the variable can be accessed. The types of scopes in Java are:
• Local Scope: Variables declared inside a method or block are accessible only within that method or
block.
• Instance Scope: Variables declared inside a class but outside any method or block, and without the
static keyword, are called instance variables. They can be accessed by any method in the class, and
each object of the class has its own copy.
• Class/Static Scope: Variables declared with the static keyword in a class are shared among all
instances of the class and can be accessed via the class name.
The final keyword is used in Java to indicate that a value or implementation cannot be changed:
Access modifiers in an abstract class control the visibility of its members (fields, methods, etc.):
Even though an abstract class can have private methods or variables, they cannot be directly accessed by
subclasses but can be used within the abstract class itself.
An exception in Java is an event that occurs during the execution of a program that disrupts its normal flow.
Exceptions are objects that Java programs create when a problem arises, such as an arithmetic error or a file not
found error. Exceptions can be caught and handled to prevent the program from crashing.
• Abstract Class:
o Can have both abstract (unimplemented) and concrete (implemented) methods.
o Can have constructors and instance variables.
o Can use access modifiers to control visibility of methods and variables.
• Interface:
o All methods are abstract by default (until Java 8 introduced default methods).
o Cannot have instance variables, only constants (static and final by default).
o Does not have constructors.
o A class can implement multiple interfaces, but can extend only one abstract class.
The main thread is the thread that begins execution of a Java program. When a Java program starts, the JVM
creates the main thread, which then runs the main() method. This thread is important because it is the primary
thread of execution, and other threads can be spawned from it.
6 Marks
1. Explain the difference between an interface and an abstract class in Java.
1) Abstract class can have abstract and Interface can have only abstract methods. Since Java 8,
non-abstract methods. it can have default and static methods also.
4) Abstract class can provide the Interface can't provide the implementation of
implementation of interface. abstract class.
7) An abstract class can be extended using An interface can be implemented using keyword
keyword "extends". "implements".
8) A Java abstract class can have class
Members of a Java interface are public by default.
members like private, protected, etc.
9)Example: Example:
public abstract class Shape{ public interface Drawable{
public abstract void draw(); void draw();
} }
2. Discuss how variable scope affects memory management and performance in Java.
In Java, variable scope directly impacts memory management and performance by determining how long a
variable exists in memory and how frequently memory is allocated and deallocated.
1. Local Scope
• Description: Variables declared inside a method or block (local variables) have local scope and exist
only within the method/block in which they are declared.
• Memory Management: Local variables are stored in the stack memory. They are created when the
method is invoked and are automatically removed when the method execution finishes.
• Impact on Performance:
o Memory Efficiency: Because stack memory is automatically managed, local variables are
very efficient in terms of memory usage. They don’t consume heap memory, reducing the
potential for memory leaks.
o Lifetime: Local variables have a short lifespan, so they are garbage collected quickly after the
method/block finishes execution.
o No Overhead of Garbage Collection: Since local variables are deallocated as soon as the
method exits, there is no involvement of the garbage collector, which reduces overhead.
Example:
2. Instance Scope
• Description: Instance variables are declared in a class but outside any method. They are tied to specific
instances of the class (objects).
• Memory Management: Instance variables are stored in the heap memory as part of the object. They
exist as long as the object they belong to exists.
• Impact on Performance:
o Heap Usage: Since instance variables are stored in the heap, they are subject to garbage
collection when the object is no longer referenced.
o Garbage Collection Overhead: The garbage collector has to manage instance variables when
they go out of scope (when the object becomes unreachable), which adds overhead compared
to local variables.
o Potential for Memory Leaks: If objects (and their instance variables) are not properly
managed (e.g., if they remain referenced unintentionally), they will stay in memory, leading to
memory leaks and reduced performance.
Example:
class Car {
int speed; // Instance variable 'speed'
}
• Description: Static variables are declared in a class using the static keyword and are shared among all
instances of the class.
• Memory Management: Static variables are stored in a special part of the heap memory called the
method area (or meta space). They exist for the lifetime of the program, regardless of the number of
objects created.
• Impact on Performance:
o Longer Lifetime: Static variables exist for the entire runtime of the application, which can
lead to excessive memory consumption if not carefully managed.
o Efficient for Shared Data: Static variables can improve performance in cases where shared
data is needed, as multiple instances of the class don’t have to store separate copies of the
same data.
o Risk of Excessive Memory Usage: Since static variables remain in memory until the class is
unloaded (which typically happens when the JVM shuts down), they may lead to higher
memory usage over time if they are not essential or are overly large.
Example:
class Car {
3. What are default access modifiers in Java? Explain their effect on class members.
• Effect: When a class, method, or variable is declared with no explicit access modifier, it is assigned
package-private access, meaning it is accessible only by classes within the same package. Classes,
methods, and variables with default access cannot be accessed by classes from other packages.
• Syntax: Simply declare the class or member without any access modifier.
• Fields (Variables): If a class member variable (field) is declared without an access modifier, it can be
accessed by all other classes within the same package, but not from outside the package.
class Example {
int defaultVar; // This is package-private
}
class AnotherExample {
void someMethod() {
Example example = new Example();
example.defaultVar = 10; // Allowed because they are in the same package
}
}
If another class in a different package tries to access defaultVar, it would result in a compile-time error.
• Methods: Similar to fields, if a method has no explicit access modifier, it can be called from any other
class within the same package but not from classes in other packages.
class MyClass {
void defaultMethod() {
// method implementation
}
}
class SamePackageClass {
void anotherMethod() {
MyClass obj = new MyClass();
obj.defaultMethod(); // Accessible within the same package
}
}
• Classes: If a class itself has no access modifier, it is package-private and can be used only within the
same package. Other classes from different packages won't be able to instantiate or use this class.
class DefaultClass {
// Can only be accessed within this package
}
If you try to use DefaultClass in a class from a different package, you will get a compile-time error.
Method overriding in Java is a feature that allows a subclass (child class) to provide a specific implementation
of a method that is already defined in its superclass (parent class). The overridden method in the subclass should
have:
Purpose:
• Method overriding enables a subclass to define its own behavior while retaining the structure of the
parent class.
• It allows runtime polymorphism (dynamic method dispatch), where the method to be executed is
determined at runtime based on the object.
1. The method must have the same name, return type, and parameters as the method in the parent
class.
2. The access modifier of the overriding method cannot be more restrictive than the method in the parent
class. (For example, a protected method in the parent class cannot be overridden with a private method
in the child class.)
3. The overridden method can throw fewer, but not more, checked exceptions than the method in the
parent class.
4. The overridden method can call the method of the superclass using the super keyword.
Example of Method Overriding:
// Parent class
class Animal {
// Method to be overridden
public void sound() {
System.out.println("The animal makes a sound");
}
}
1. Checked Exceptions:
• Definition: Checked exceptions are exceptions that the compiler forces you to handle. These
exceptions are checked at compile time to ensure that the programmer has taken care of these
exceptions by either using a try-catch block or declaring the exception using the throws keyword.
• Characteristics:
o Must be either caught or declared in the method signature using the throws keyword.
o If a checked exception is not handled, the program will not compile.
o They usually represent conditions that can be reasonably expected to occur and can be
recovered from (e.g., file not found, invalid user input).
• Common Checked Exceptions:
o IOException
o SQLException
o ClassNotFoundException
o FileNotFoundException
• Example:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
• Definition: Unchecked exceptions are exceptions that are not checked at compile time. These are
typically programming errors or unexpected conditions that can be caught during runtime but are not
required to be handled or declared in the method signature.
• Characteristics:
o Do not need to be explicitly caught or declared in the method signature.
o The programmer may choose to handle them, but it’s not mandatory.
o Usually indicate programming errors, logic flaws, or runtime issues that are not expected to be
recovered from (e.g., division by zero, null pointer access).
• Common Unchecked Exceptions (subclasses of RuntimeException):
o NullPointerException
o ArrayIndexOutOfBoundsException
o ArithmeticException
o IllegalArgumentException
• Example:
1. Mutual Exclusion: At least one resource must be held in a non-shareable mode. If one thread holds a
resource, other threads cannot access it.
2. Hold and Wait: A thread holding a resource is waiting to acquire additional resources that are
currently being held by other threads.
3. No Preemption: Resources cannot be forcibly taken away from a thread; the thread holding the
resource must release it voluntarily.
4. Circular Wait: A circular chain of threads exists, where each thread holds at least one resource that
the next thread in the chain is waiting for.
To prevent deadlock, the system needs to break one or more of the four necessary conditions. Here are some
strategies:
1. Mutual Exclusion: Reduce the scope of mutual exclusion by allowing resources to be shared
whenever possible. For example, using readers-writers locks allows multiple readers or a single writer
but not both simultaneously.
2. Hold and Wait Prevention:
o Resource allocation at once: Ensure that a thread acquires all the resources it needs before
starting execution. If not all resources are available, it must release the ones it has and try
again later.
o Non-blocking synchronization: Use techniques like lock-free data structures and atomic
operations to avoid threads waiting for each other.
3. No Preemption:
o Allow resources to be preempted if a thread holding the resource is waiting for other
resources. For instance, if a thread cannot acquire all the resources it needs, it may release its
current resources to avoid a deadlock.
4. Circular Wait Prevention:
o Impose an ordering on resources: Assign a numerical priority to each resource. Threads can
request resources only in increasing order of priority. This prevents circular wait by
eliminating cycles.
o Timeout mechanism: Set time limits for how long a thread can hold onto a resource before
releasing it.
Deadlock Avoidance
• Banker's Algorithm: This algorithm is used to avoid deadlock by allocating resources only if the
system can ensure that after the allocation, it can still avoid a deadlock situation. It simulates the
allocation of resources and checks if the system remains in a safe state.
• Lock Hierarchies: By defining a strict order in which locks must be acquired, deadlock can be
avoided. This ensures that circular dependencies do not form.
In Java, an abstract class is a class that cannot be instantiated and is used as a blueprint for other classes. It may
contain both abstract methods (methods without a body) and concrete methods (methods with a body). The
purpose of an abstract class is to provide common behavior for related subclasses while ensuring that certain
methods are implemented in each subclass.
Key Points:
Syntax in Java
Example in Java
// Abstract class
abstract class Animal {
// Concrete method
void sleep() {
System.out.println("This animal is sleeping");
}
}
// Subclass of Animal
class Dog extends Animal {
// Subclass of Animal
class Cat extends Animal {
// Calling methods
dog.sound(); // Output: Bark
dog.sleep(); // Output: This animal is sleeping
Output:
Bark
This animal is sleeping
Meow
This animal is sleeping
8. Write a note on interfaces and present the syntax for defining an interface.
An interface in Java is a reference type similar to a class that can contain only constants, method signatures,
default methods, static methods, and nested types. It is used to specify a contract that implementing classes must
follow. Interfaces enable a form of multiple inheritance, allowing a class to implement multiple interfaces,
thereby facilitating polymorphism and decoupling.
1. Method Declarations: Interfaces can declare methods that must be implemented by classes that choose
to implement the interface.
2. Default Methods: Introduced in Java 8, these methods have a body and can be used to provide default
behavior for classes.
3. Static Methods: Interfaces can have static methods that can be called independently of any instance.
4. Constants: All fields declared in an interface are implicitly public, static, and final.
5. Multiple Inheritance: A class can implement multiple interfaces, allowing it to inherit behavior from
multiple sources.
// Abstract method
void methodName();
Example of an Interface
// Defining an interface
public interface Animal {
// Abstract method
void sound();
// Default method
default void sleep() {
System.out.println("This animal is sleeping");
}
}
Output
Bark
This animal is sleeping
Meow
This animal is sleeping
9. Name the five key words and present an outline of an exception-handling block with syntax.
In Java, the five key keywords used for exception handling are:
try {
// Code that may throw an exception
} catch (ExceptionType e) {
// Code to handle the exception
} finally {
// Code that will always execute (optional)
}
Example
Expected Output:
10. Why is Thread a light weight process? Explain the life cycle of thread with the various states.
A thread is often referred to as a lightweight process because it shares the same memory space and resources
with other threads within the same process. Here are some key reasons why threads are considered lightweight:
1. Resource Sharing: Threads within the same process share resources like memory, file descriptors, and
system resources. This makes context switching between threads faster than switching between
processes, as threads do not require their own separate memory space.
2. Lower Overhead: Creating and managing threads incurs less overhead compared to processes.
Threads have a smaller memory footprint, and switching between threads involves less system
overhead since they share the same address space.
3. Efficient Communication: Communication between threads is more efficient than communication
between processes since they share the same memory space, allowing for easy data sharing.
1. New:
o A thread is in the "New" state when it is created but not yet started.
o Example: Thread thread = new Thread();
2. Runnable:
o A thread enters the "Runnable" state after the start() method is called.
o It may be running or waiting for CPU time to run.
o It can transition back and forth between the "Runnable" and "Running" states.
3. Blocked:
o A thread enters the "Blocked" state when it is waiting for a monitor lock (a synchronization
mechanism) to enter a synchronized block or method.
o It will remain in this state until it can acquire the lock.
4. Waiting:
o A thread is in the "Waiting" state when it is waiting for another thread to perform a particular
action (like notifying or interrupting).
o This can happen through methods like Object.wait(), Thread.join(), or
LockSupport.park().
5. Timed Waiting:
o A thread enters the "Timed Waiting" state when it waits for a specified period.
o This occurs through methods like Thread.sleep(milliseconds),
Object.wait(milliseconds), or Thread.join(milliseconds).
6. Terminated:
o A thread enters the "Terminated" state when it has completed its execution or has been
terminated due to an exception or other factors.
o This state cannot be transitioned out of.
In Java, you can catch multiple exceptions using multiple catch blocks or by using a single catch block with the
pipe (|) operator. This feature allows you to handle different types of exceptions that may arise from the same
block of code, making your error handling more efficient and concise.
You can specify different catch blocks for different exception types. This approach is useful when you want to
handle each exception type differently.
Example
public class MultipleCatchExample {
public static void main(String[] args) {
try {
// Code that may throw exceptions
String str = null;
System.out.println(str.length()); // This will throw NullPointerException
Output
You can also catch multiple exceptions in a single catch block using the pipe (|) operator. This is useful when
you want to handle multiple exceptions in the same way.
Example
public class MultipleCatchExample {
public static void main(String[] args) {
try {
// Code that may throw exceptions
String str = null;
System.out.println(str.length()); // This will throw NullPointerException
Output
Cooperation (Inter-thread communication) is a mechanism in which a thread is paused running in its critical
section and another thread is allowed to enter (or lock) in the same critical section to be executed.It is implemented
by following methods of Object class:
o wait()
o notify()
o notifyAll()
1) wait() method
The wait() method causes current thread to release the lock and wait until either another thread invokes the notify()
method or the notifyAll() method for this object, or a specified amount of time has elapsed.
The current thread must own this object's monitor, so it must be called from the synchronized method only
otherwise it will throw exception.
Method Description
2) notify() method
The notify() method wakes up a single thread that is waiting on this object's monitor. If any threads are waiting
on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the
implementation.
Syntax:
3) notifyAll() method
Syntax:
Test.java
1. class Customer{
2. int amount=10000;
3.
4. synchronized void withdraw(int amount){
5. System.out.println("going to withdraw...");
6.
7. if(this.amount<amount){
8. System.out.println("Less balance; waiting for deposit...");
9. try{wait();}catch(Exception e){}
10. }
11. this.amount-=amount;
12. System.out.println("withdraw completed...");
13. }
14.
15. synchronized void deposit(int amount){
16. System.out.println("going to deposit...");
17. this.amount+=amount;
18. System.out.println("deposit completed... ");
19. notify();
20. }
21. }
22.
23. class Test{
24. public static void main(String args[]){
25. final Customer c=new Customer();
26. new Thread(){
27. public void run(){c.withdraw(15000);}
28. }.start();
29. new Thread(){
30. public void run(){c.deposit(10000);}
31. }.start();
32.
33. }}
Output:
going to withdraw...
Less balance; waiting for deposit...
going to deposit...
deposit completed...
withdraw completed
10 Marks
1.Summarize the following with an example program
i. Arithmetic exception (5)
Definition: An ArithmeticException is thrown when an illegal arithmetic operation occurs, such as dividing by
zero. It is a runtime exception, meaning it can occur during the execution of the program.
Common Causes:
1. Division by zero.
2. Performing operations that exceed the limits of the data type (e.g., integer overflow).
Example Program:
public class ArithmeticExceptionExample {
public static void main(String[] args) {
int a = 10;
int b = 0; // This will cause an ArithmeticException
try {
int result = a / b; // Attempting division by zero
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Error: Division by zero is not allowed!");
}
}
}
Output:
Common Causes:
Example Program:
java
Copy code
public class ArrayIndexOutOfBoundsExceptionExample {
public static void main(String[] args) {
int[] numbers = {1, 2, 3}; // Array of size 3
try {
// Attempting to access an index that is out of bounds
System.out.println(numbers[3]); // Index 3 is out of bounds
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Error: Array index is out of bounds!");
}
}
}
Output:
The try-catch-throw paradigm in Java is a structured approach for handling exceptions. It allows developers to
anticipate potential errors in their code and respond to them gracefully, ensuring the program can continue
running or terminate without crashing unexpectedly.
Components:
Example Program:
public class TryCatchThrowExample {
Exception specification is a mechanism that allows a method to declare which exceptions it can throw. In Java,
this is done using the throws keyword in the method signature. It provides information to the caller of the
method about the exceptions that need to be handled.
Key Points:
Example Program:
public class ExceptionSpecificationExample {
In Java, classes and interfaces serve different purposes and have distinct characteristics. Here are the key
differences:
// Main class
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
In Java, an interface can extend another interface, allowing the new interface to inherit the abstract methods of
the parent interface. This is useful for creating a hierarchy of interfaces.
Example Program
// Parent interface
interface Animal {
void sound(); // abstract method
}
// Main class
public class InterfaceExtensionExample {
public static void main(String[] args) {
Pet dog = new Dog();
To process a list of data files concurrently in Java using threads, we can use the ExecutorService to manage a
pool of threads. Each thread will read a file, simulate processing by sleeping for a few seconds, and then write
the result to the console. To ensure that all threads complete before the program exits, we can use the invokeAll
method to wait for all tasks to finish.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Override
public void run() {
try {
System.out.println("Processing file: " + fileName);
// Simulating file processing by sleeping for 2 seconds
Thread.sleep(2000);
// Simulate writing the result
System.out.println("Finished processing file: " + fileName);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Thread was interrupted: " + e.getMessage());
}
}
}
try {
// Wait for all tasks to finish
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
executorService.shutdownNow(); // Forcefully shutdown if not terminated in time
}
} catch (InterruptedException e) {
executorService.shutdownNow(); // Force shutdown if the current thread is interrupted
System.out.println("Interrupted during waiting: " + e.getMessage());
}
Output
5.Describe the role of abstract classes and interfaces in achieving abstraction in Java. Illustrate with
examples.
1. Abstract Classes
Definition: An abstract class is a class that cannot be instantiated on its own and may contain both abstract
methods (without implementations) and concrete methods (with implementations). Abstract classes allow you to
provide some default behavior while forcing subclasses to implement specific behaviors.
Role in Abstraction:
• An abstract class serves as a base for subclasses, allowing them to inherit common behavior and state
while enforcing the implementation of certain methods.
• It provides a way to define a template for a group of related classes.
// Constructor
public Animal(String name) {
this.name = name;
}
// Abstract method
abstract void sound();
// Concrete method
void eat() {
System.out.println(name + " is eating.");
}
}
// Subclass
class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
void sound() {
System.out.println(name + " barks.");
}
}
// Main class
public class AbstractClassExample {
public static void main(String[] args) {
Animal dog = new Dog("Buddy");
dog.sound(); // Output: Buddy barks.
dog.eat(); // Output: Buddy is eating.
}
}
Output:
Buddy barks.
Buddy is eating.
2. Interfaces
Definition: An interface in Java is a reference type that defines a set of abstract methods (without
implementations) that a class can implement. Interfaces can also contain default methods (with
implementations) and static methods.
Role in Abstraction:
• Interfaces provide a way to define a contract for classes that implement them, ensuring that specific
methods are implemented.
• They enable multiple inheritance by allowing a class to implement multiple interfaces.
Example of Interface
// Interface
interface Vehicle {
void start();
void stop();
}
@Override
public void stop() {
System.out.println("Car is stopping.");
}
}
// Main class
public class InterfaceExample {
public static void main(String[] args) {
Vehicle myCar = new Car();
myCar.start(); // Output: Car is starting.
myCar.stop(); // Output: Car is stopping.
}
}
Output:
Car is starting.
Car is stopping.
6. Explain the concept of method overloading in Java. Provide an example that demonstrates how it
works.
Definition: Method overloading in Java is a feature that allows a class to have more than one method with the
same name, as long as the methods have different parameter lists. This is a way to define multiple behaviors for
the same method name based on different input parameters.
Key Points:
class Calculator {
Output
7. Describe the life cycle of a thread in Java. What are the different states of a thread? Provide a detailed
explanation with examples of how threads transition between states.
Thread States
1. New: The thread is in this state when it is created but not yet started. It is an object of the Thread class
but hasn't begun its execution.
2. Runnable: The thread is in the runnable state when it is ready to run and waiting for the CPU to
execute it. A thread can enter this state from the new state or from other states.
3. Blocked: The thread is in the blocked state when it is waiting for a monitor lock to enter or re-enter a
synchronized block/method.
4. Waiting: A thread is in the waiting state when it is waiting indefinitely for another thread to perform a
particular action (like sending a notification).
5. Timed Waiting: This state is similar to the waiting state, but it occurs when a thread waits for another
thread to perform an action for a specified period of time.
6. Terminated: The thread is in the terminated state when it has completed its execution or has been
terminated due to an exception.
State Transition Diagram
1. New to Runnable:
o A thread enters the runnable state when the start() method is invoked on the Thread object.
o Example:
2. Runnable to Running:
o A thread moves from the runnable state to the running state when the scheduler allocates CPU
time for the thread.
o The JVM does not provide explicit methods to move a thread to the running state; it depends
on the thread scheduler.
3. Running to Blocked:
o A thread moves to the blocked state when it tries to access a synchronized block or method
that is already locked by another thread.
o Example:
// If Thread A is executing this method, Thread B will be blocked if it tries to access it.
4. Running to Waiting:
o A thread can enter the waiting state by calling methods like wait(), join(), or
LockSupport.park().
o Example:
synchronized (object) {
object.wait(); // Thread goes into Waiting state
}
synchronized (object) {
object.notify(); // Notifies waiting threads to enter Runnable state
}
7. Running to Terminated:
o A thread enters the terminated state when it completes its execution or if it terminates due to
an exception.
o Example:
Example Code
// Letting the main thread sleep for a bit to allow the threads to run
Thread.sleep(500);
Output
The LibraryItem abstract class defines common attributes like title and ID, along with an abstract method
displayDetails().
The Borrowable and Reservable interfaces define methods for borrowing and reserving items.
interface Borrowable {
void borrowItem();
void returnItem();
}
interface Reservable {
void reserveItem();
void cancelReservation();
}
The classes Book, Magazine, and DVD extend LibraryItem and implement Borrowable and Reservable where
applicable.
Book Class
class Book extends LibraryItem implements Borrowable, Reservable {
private boolean isBorrowed;
private boolean isReserved;
public Book(String title, String id) {
super(title, id);
this.isBorrowed = false;
this.isReserved = false;
}
@Override
void displayDetails() {
System.out.println("Book Title: " + title);
System.out.println("ID: " + id);
System.out.println("Borrowed: " + isBorrowed);
System.out.println("Reserved: " + isReserved);
}
@Override
public void borrowItem() {
if (!isBorrowed) {
isBorrowed = true;
System.out.println(title + " has been borrowed.");
} else {
System.out.println(title + " is already borrowed.");
}
}
@Override
public void returnItem() {
if (isBorrowed) {
isBorrowed = false;
System.out.println(title + " has been returned.");
} else {
System.out.println(title + " was not borrowed.");
}
}
@Override
public void reserveItem() {
if (!isReserved) {
isReserved = true;
System.out.println(title + " has been reserved.");
} else {
System.out.println(title + " is already reserved.");
}
}
@Override
public void cancelReservation() {
if (isReserved) {
isReserved = false;
System.out.println(title + " reservation has been canceled.");
} else {
System.out.println(title + " was not reserved.");
}
}
}
Magazine Class
class Magazine extends LibraryItem implements Borrowable {
private boolean isBorrowed;
@Override
void displayDetails() {
System.out.println("Magazine Title: " + title);
System.out.println("ID: " + id);
System.out.println("Borrowed: " + isBorrowed);
}
@Override
public void borrowItem() {
if (!isBorrowed) {
isBorrowed = true;
System.out.println(title + " has been borrowed.");
} else {
System.out.println(title + " is already borrowed.");
}
}
@Override
public void returnItem() {
if (isBorrowed) {
isBorrowed = false;
System.out.println(title + " has been returned.");
} else {
System.out.println(title + " was not borrowed.");
}
}
}
DVD Class
class DVD extends LibraryItem implements Borrowable, Reservable {
private boolean isBorrowed;
private boolean isReserved;
@Override
void displayDetails() {
System.out.println("DVD Title: " + title);
System.out.println("ID: " + id);
System.out.println("Borrowed: " + isBorrowed);
System.out.println("Reserved: " + isReserved);
}
@Override
public void borrowItem() {
if (!isBorrowed) {
isBorrowed = true;
System.out.println(title + " has been borrowed.");
} else {
System.out.println(title + " is already borrowed.");
}
}
@Override
public void returnItem() {
if (isBorrowed) {
isBorrowed = false;
System.out.println(title + " has been returned.");
} else {
System.out.println(title + " was not borrowed.");
}
}
@Override
public void reserveItem() {
if (!isReserved) {
isReserved = true;
System.out.println(title + " has been reserved.");
} else {
System.out.println(title + " is already reserved.");
}
}
@Override
public void cancelReservation() {
if (isReserved) {
isReserved = false;
System.out.println(title + " reservation has been canceled.");
} else {
System.out.println(title + " was not reserved.");
}
}
}
9. Provide a demonstration in a Main class that creates instances of each item and calls their methods.
To provide a demonstration in a Main class that creates instances of different items and calls their methods, we
need to start by defining a few example classes. Let’s say we have three item types: Book, Magazine, and
Journal. Each class will have its own methods for demonstration.
Item Classes
// Book.java
class Book {
private String title;
private String author;
// Magazine.java
class Magazine {
private String title;
private int issueNumber;
// Journal.java
class Journal {
private String title;
private String editor;
Main Class
Explanation
1. Classes: We have three classes: Book, Magazine, and Journal. Each class has a constructor and two
methods—one for performing an action related to the item and another for providing information about
it.
2. Main Class: The Main class creates instances of each of these item classes and calls their methods to
demonstrate their functionality.
Output
Reading the book: The Great Gatsby by F. Scott Fitzgerald
Book Info: The Great Gatsby by F. Scott Fitzgerald
Browsing the magazine: National Geographic, Issue #202
Magazine Info: National Geographic, Issue #202
Reviewing the journal: Nature edited by Magdalena Skipper
Journal Info: Nature edited by Magdalena Skipper