0% found this document useful (0 votes)
2 views25 pages

Java

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)
2 views25 pages

Java

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/ 25

DAY-1

Java program execution


The execution of a Java program involves multiple stages, from writing the source code to running it on a
machine. Java is known for its "Write Once, Run Anywhere" philosophy, which is enabled by the Java Virtual
Machine (JVM). Here's how a Java program runs:

1. Writing the Source Code

You write Java code in .java files using a text editor or an Integrated Development Environment (IDE) like
Eclipse, IntelliJ IDEA, or VS Code.

2. Compiling the Source Code

After writing the Java source code, it needs to be compiled. The compilation process involves converting
human-readable code into bytecode that can be executed by the JVM.

 The Java compiler (javac) translates the .java file into a bytecode file with the .class extension.
 This bytecode is platform-independent and can be run on any machine with a JVM.

3. Loading the Bytecode into the JVM

The next step is to run the compiled bytecode. This is where the Java Virtual Machine (JVM) comes into
play. The JVM is responsible for executing the bytecode on a specific platform (Windows, Linux, macOS,
etc.).

Running the Java Program:


java MyClass

When you run java MyClass, the following happens:

 The JVM loads the MyClass.class file.


 The Class Loader component of the JVM loads the class and links it with the required libraries.
 The JVM’s Execution Engine translates bytecode into machine code (native instructions) using either
interpretation or Just-In-Time (JIT) compilation.

1. Public static void main(String[] args)

This is the main method that serves as the entry point of the program. Each part of the method has a specific
purpose:

 public: It is a access specifier. It makes the main method accessible to other parts of the program.
 static: Indicates that this method belongs to the class, not to instances of it. This allows the method to be
called without creating an object of the class.
 void: Specifies that the method does not return any value.
 main: This is the name of the method. It's a special method in Java because it's the starting point when the
program is executed.
 String[] args: This is an array of String objects, which can store command-line arguments passed to the
program.

2. System.out.println("Hello world");
This line prints the text "Hello world" to the console.

 System: This is a class in the java.lang package that provides access to system-related resources.
 out: This is an object of the PrintStream class, part of System. It represents the standard output stream
(console output).
 println: This is a method of PrintStream that prints a message to the console and then moves the cursor to
the next line.

You can have multiple main methods in a Java program, but they must have different method signatures, i.e.,
the parameter list must differ. However, only the main method with the signature public static void
main(String[] args) is recognized as the entry point of the program when you run it.

When you run the program, only the public static void main(String[] args) method will be called by
default. The other main methods won't be invoked unless you call them explicitly within the program.

public class MyClass {

public static void main(String[] args) {

System.out.println("Main method with String[] args");

int[] numbers = {1, 2, 3};

main(numbers); // Calls the int[] main method

main(); // Calls the no-argument main method

public static void main(int[] args) {

System.out.println("Main method with int[] args");

public static void main() {

System.out.println("Main method with no arguments");

}
When you try to print the args array directly using System.out.println(args), Java does not print the contents of the array
but instead prints a memory reference (the hash code) of the array object.

System.out.println(args); // This will print the reference to the args array

OUTPUT :- [Ljava.lang.String;@15db9742

This output is a reference to the String[] array, which indicates:

 [L means it's an array.


 java.lang.String is the type of the array (an array of String).
 @15db9742 is the memory address or hash code of the array (this will vary with each run).

System.out.println(Arrays.toString(args)); // This will print the array contents

Source Code (.java)

Compiler (javac)

Bytecode (.class)

JVM (Class Loader → Bytecode Verifier → Execution Engine)

Native Code Execution on Host Machine

DAY-2
In Java, type casting refers to converting a variable from one data type to another. This process can be either
implicit (automatic) or explicit (manual). These conversions are also known as widening conversion and
narrowing conversion, respectively.

1. Implicit Type Casting (Widening Conversion):


 Definition: This is an automatic conversion performed by Java when you assign a smaller or compatible
type to a larger type. Since no data is lost in this conversion, Java does it implicitly (without requiring
extra effort from the programmer).
 Also Known As:
Widening Casting or Widening Primitive Conversion

Automatic Type Conversion

 Types Supported: Widening occurs when converting from:

byte → short → int → long → float → double

char → int → long → float → double

 Why It's Safe: Because a smaller type can fit into a larger type without losing information. For example,
an int can easily fit into a double without losing precision.

2. Explicit Type Casting (Narrowing Conversion):


 Definition: This is a manual type conversion where the programmer explicitly converts a larger type into
a smaller or less compatible type. Since there might be a risk of data loss, Java requires an explicit cast to
confirm that the conversion is intentional.
 Also Known As:

Narrowing Casting or Narrowing Primitive Conversion

Manual Type Conversion

Types Supported: Narrowing occurs when converting from:

 double → float → long → int → short → byte


 In this process, precision or information might be lost. For example, converting a double to an int will
truncate the decimal part.

Why It's Risky: Narrowing can cause data loss or imprecise values. For example, converting a float to an
int results in the fractional part being discarded.

Upcasting and Downcasting in Java objects

DAY-3
1. IF-ELSE :-
Key Differences:

 Type of condition:

 In C++, any value can be treated as a condition (non-zero for true, zero for false).
 In Java, the condition must evaluate to boolean.
 Compilation error: In Java, using non-boolean expressions in if results in a compilation error, while C++
allows such expressions.

2. SWITCH :-
The switch statement exists in both C++ and Java, but the rules governing the types of expressions allowed,
and the behavior are slightly different.

C++ switch:

 The expression in the switch statement can be an integral type (i.e., int, char, enum, or short), but it
cannot be floating-point (float, double).
 Strings are not allowed as switch expressions in C++.
 Fall-through: Like in Java, the switch statement in C++ does not automatically break after each case.
You need to use the break statement to prevent fall-through.

Java switch:

 The expression in the switch statement can be an integral type (byte, short, int, char), but also String,
enum, and certain wrapper types (Byte, Integer, etc.).
 Floating-point (float, double) types are still not allowed in Java.
 Switching on String values is supported in Java (from Java 7 onwards).
 Fall-through: Similar to C++, you need break statements to prevent fall-through. However, in Java 12+,
the switch expression uses -> and does not require break statements.

Scanner sc = new Scanner(System.in);

1. Class: Scanner
 What it is: Scanner is a built-in class in Java from the java.util package.
 Purpose: It's used to take input from various input sources like the console, files, or even strings.
 Use here: In this context, Scanner is used to capture input from the user through the console.

2. Object: sc
 What it is: sc is an object of the Scanner class.
 Purpose: It represents the instance of the Scanner class, and through this object, you can call various
methods of the Scanner class to read user input (like sc.nextInt(), sc.nextLine(), etc.).
 Use here: sc is being created to call input methods to read data entered by the user.

3. Constructor: new Scanner(System.in)


 What it is: new Scanner() is the constructor of the Scanner class, which creates an instance (object) of
Scanner.
 Purpose: It initializes the Scanner object to work with a specific input source.
 Use here: System.in is passed as an argument to the constructor, telling the Scanner to take input from the
standard input stream (the keyboard in most cases).

4. System.in
 What it is: System.in is a standard input stream in Java.
 Purpose: It provides a way to read input data from the console.
 Use here: It directs the Scanner to take input from the user via the keyboard.

STRINGS
String str1 = "Hello"; Using String Literal

String str2 = new String("Hello"); Using the new Keyword

Key Differences:

1. String Pool vs Heap Memory:


String Literal:

 When you create a string using a string literal (String str1 = "Hello";), the string is stored in a
special area of memory called the String Pool.
 If another string with the same value already exists in the pool, Java will reuse that string, rather
than creating a new one.
 This is more memory-efficient because it avoids creating multiple copies of the same string.

Using new Keyword:

 When you create a string using the new keyword (String str2 = new String("Hello");), Java will
always create a new object in the heap memory, even if a string with the same value exists in the
String Pool.
 It does not check for existing strings with the same value in the pool, so this approach consumes
more memory.

2. Object Creation:
String Literal:

 Only one object is created if the string value is not already present in the String Pool. If it is
already there, no new object is created, and the reference points to the existing object.

Using new Keyword:

 A new object is created every time, regardless of whether the same string exists in the String Pool.

3. String Interning:
String Literal: Strings created as literals are automatically interned (stored in the String Pool).

Using new Keyword: The new keyword doesn't automatically intern the string. However, you can
manually add the string to the pool using the intern() method
Object Creation

<ClassName> <ref. var> = new <Class Constructor>();

Dog dog1 = new Dog();

This Java statement, Dog dog1 = new Dog();, involves object creation and can be broken down
into several parts:

1. Class Name (Dog):

 Dog is the name of the class. In Java, objects are created from classes, which act as
blueprints. Here, the Dog class represents the type of object you are creating.

2. Object Reference Variable (dog1):

 dog1 is the name of the object reference variable. It holds the reference (address in
memory) to the newly created object. This variable will allow you to interact with the
object's properties and methods.

3. Assignment Operator (=):

 The = is the assignment operator. It assigns the reference of the newly created object (new
Dog()) to the variable dog1.

4. new Keyword:

 The new keyword is used to allocate memory for the new object. It dynamically creates a
new instance of the Dog class.

5. Constructor Call (new Dog()):

 new Dog() is the constructor call. It invokes the constructor of the Dog class to initialize
the newly created object. If no constructor is explicitly defined in the class, the default
constructor (with no parameters) is automatically called.

Ways to Create an Object

1. Using an Object Reference Variable Without Immediate Initialization

Dog dog1 = new Dog();

2. Using an Object Reference Variable Without Immediate Initialization


You can declare the reference variable first and initialize it later.

Dog dog1; // Declare the reference variable


dog1 = new Dog(); // Initialize it later with a new object

3. Using a Constructor with Parameters

If the class has a constructor that accepts parameters, you can pass values during object creation.

Dog dog1 = new Dog("Buddy", 2);

4. Using a Factory Method

A factory method is a method that returns an object. Instead of using new, you call a method that
returns an instance of the class.

Dog dog1 = Dog.createDog();


[ Assuming Dog class has a static method createDog() ]

5. Anonymous Object Creation

Sometimes, you create an object but don't assign it to a variable (if you're just using it for a one-
time operation).

new Dog().bark(); // Calls the bark method without storing the object

6. Object Creation Using Reflection (Advanced)

You can use reflection to create an object if you don't know the class at compile time.

Dog dog1 = (Dog) Class.forName("Dog").newInstance();

7. Cloning an Object

You can create a new object by cloning an existing one (assuming the class implements
Cloneable).

Dog dog1 = new Dog();


Dog dog2 = (Dog) dog1.clone(); // Create a new object by cloning

8. Deserialization

An object can also be created by reading it from a file (i.e., deserializing).

ObjectInputStream in = new ObjectInputStream(new FileInputStream("dog.dat"));

Dog dog1 = (Dog) in.readObject();


An anonymous object in Java is an object that is created without being assigned to a reference variable. It
is typically used for one-time use, where the object is not needed for later access. Since the object has no
reference, it becomes eligible for garbage collection as soon as the operation using it is complete.

POINTS TO REMEMBER
Constructor Availability :- If your class does not define a constructor, the Java compiler automatically provides a
default constructor (a no-argument constructor). However, if a parameterized constructor is defined and no default
constructor is, attempting to create an object without arguments will result in a compilation error.

Object Scope and Lifetime :- Local objects (created inside methods) will be destroyed once the method
exits, while objects created as class-level fields (instance variables) will live as long as the object instance
remains in memory.

INHERITANCE
Constructor in Inheritance:
 When a subclass object is created, the constructor of the superclass is invoked first, and then the subclass's
constructor is called.
 The subclass can explicitly invoke a superclass constructor using super().

ACCESS SPECIFIERS

Key Notes:
 Private members are only accessible within the same class.
 Default (no modifier) members are accessible within the same package but not outside the
package.
 Protected members are accessible within the same package and also by subclasses in other
packages.
 Public members are accessible from anywhere.

this Keyword
The this keyword in Java is a reference variable that refers to the current object, the instance of the class from which
it is called. It is commonly used in several contexts within a class.

Key Points about this


1. Reference to the Current Object:
 this is used to refer to the current object within an instance method or a constructor.
 It helps differentiate between class attributes and parameters when they have the same
name.

2. Calling Another Constructor :- It can be used to call another constructor in the same class.
This is known as constructor chaining.

3. Passing the Current Object :- this can be passed as an argument to other methods or
constructors.

4. Returning the Current Object :- It can be returned from a method, allowing method chaining.

Where this Cannot Be Used

 Static Context: In static methods or static blocks, this cannot be used because static members
belong to the class rather than any specific instance.

super KEYWORD
The super keyword in Java is used to refer to the parent class (superclass) of the current
object. It serves various purposes related to inheritance.

Key Points about super


1. Accessing Parent Class Methods :- You can use super to call methods from the parent class
that have been overridden in the subclass.
2. Accessing Parent Class Constructors :- super can be used to call the constructor of the
parent class from the subclass constructor. This is important for initializing parent class
attributes
3. Accessing Parent Class Fields :- If there is a field in the parent class with the same name as
a field in the subclass, super can be used to access the parent class's field.

When to Use super


 Calling Overridden Methods: When you want to access a method in the parent class that has
been overridden in the subclass.
 Constructor Initialization: When you want to ensure the parent class constructor is called
during the creation of a subclass instance.
 Field Disambiguation: When you have a naming conflict between subclass and parent class
fields.

Important Points
 Constructor Call: If super is used in a constructor, it must be the first statement.
 Single Inheritance: super can only refer to the immediate parent class. It cannot be used to
refer to a grandparent or any other ancestor class directly.
 Static Context: super cannot be used in static methods or static blocks, as it requires an
instance context.

final Keyword
In Java, the final keyword is used to restrict the user from making further modifications. It can
be applied to classes, methods, and variables.

In Java, the final keyword is used to restrict the user from making further modifications. It can
be applied to classes, methods, and variables. Here’s a breakdown of the different usages of the
final keyword:

1. Final Variables

 Definition: When a variable is declared as final, its value cannot be changed once it has
been initialized.
 Usage: This is commonly used for constants.

2. Final Methods

 Definition: A method declared as final cannot be overridden by subclasses.


 Usage: This is used to prevent changing the behavior of a method in derived classes.
3. Final Classes

 Definition: A class declared as final cannot be subclassed.


 Usage: This is used to prevent inheritance and ensure that the class cannot be extended.

Important Points about final


1. Initialization :- For final variables, they must be initialized once, either at the time of
declaration or within a constructor.
2. Inheritance :- A final class cannot be extended, which means no other class can inherit from it.
This is useful when you want to create immutable classes or prevent alteration of a class
structure.
3. Performance :- Methods declared as final can improve performance slightly because the
compiler can optimize calls to them, knowing they won't be overridden.
4. Immutable Classes :- Declaring a class as final can be a part of creating immutable classes,
where the state of the object cannot change after it is constructed.

Abstraction
Abstract Keyword :-

In Java, the abstract keyword is used to declare classes and methods that are incomplete and meant to be
extended or implemented by subclasses. It serves as a blueprint for other classes and ensures that certain
methods are implemented in the derived classes.

Key Points about abstract Keyword

1. Abstract Class

 Definition: An abstract class is a class that cannot be instantiated directly. It can contain both abstract
(unimplemented) and non-abstract (implemented) methods.
 Purpose: Used when you want to provide a base class with some default behavior while enforcing the
implementation of specific methods in derived classes.

2. Abstract Method

 Definition: An abstract method is a method declared without a body, meaning it has no implementation in the
abstract class.
 Purpose: Forces subclasses to provide their own implementation for this method.
 Rules:
 Must be declared inside an abstract class.
 Cannot be static or final.

3. Rules for Using abstract

 You cannot create an object of an abstract class directly.


 If a class contains even one abstract method, it must be declared as an abstract class.
 A subclass of an abstract class must either:
 Provide implementations for all abstract methods, or
 Be declared abstract itself.

4. When to Use abstract

 When you have a common base class and want to ensure certain methods are implemented in all derived classes.
 To enforce consistency across a group of subclasses.

Interfaces :-
In Java, an interface is a reference type that defines a contract or blueprint that other classes must follow. It
contains abstract methods (implicitly public and abstract) and constants (implicitly public, static, and final).
Interfaces are used to achieve abstraction and multiple inheritance in Java.

Key Points about Interfaces

1. Definition

 An interface is a collection of abstract methods and static constants.


 It allows a class to implement multiple behaviors by specifying the methods the implementing class must provide.

2. Features of Interfaces

 All methods in an interface are implicitly public and abstract.


 Fields (variables) in an interface are implicitly public, static, and final.
 A class implements an interface using the implements keyword.
 Interfaces support multiple inheritance since a class can implement multiple interfaces.

3. Implementing an Interface :- A class that implements an interface must provide implementations for all its methods
unless the class is declared abstract.

4. Extending Interfaces :- An interface can extend another interface, allowing hierarchical organization of related
functionalities.

5. Default and Static Methods in Interfaces (Java 8+)

 Default Methods: Allow interfaces to provide a default implementation for a method.


 Static Methods: Allow interfaces to define static utility methods.

6. Functional Interfaces (Java 8+) :- An interface with a single abstract method is called a functional interface. It is used
in lambda expressions and method references.

INNER CLASSES

Inner Classes

An inner class is a class defined within another class. It is associated with an instance of the outer class
and has access to all its fields and methods, including private ones.
Key Points:

1. Non-static: Inner classes are non-static by default.


2. Access: They can access the outer class's instance members directly.
3. Use Case: Used when a class is tightly bound to an instance of another class and needs access to its
members.

NESTED STATIC CLASS

A nested static class is a static class defined within another class. Unlike inner classes, it does not have
access to the outer class's instance members. It can access static members of the outer class directly.

Key Points:

1. Static: Nested static classes are not tied to an instance of the outer class.
2. Access: They can only access the outer class's static members.
3. Use Case: Used when the inner class does not require access to the instance members of the outer class.

Anonymous Classes
An anonymous class in Java is a type of inner class that has no name and is defined and instantiated in a single
statement. It is primarily used to provide a quick implementation of an interface or an abstract class, or to
override methods of an existing class without formally creating a new subclass.

Key Features of Anonymous Classes

1. No Name: The class is unnamed and declared as part of a single statement.


2. Single Instance: Typically used for one-time use, making the code concise and avoiding the need to create a
separate named class.
3. Extends/Implements: Can extend a class or implement an interface but not both simultaneously.
4. Short-Lived: Mainly used for creating short-lived objects like event listeners or callbacks.

When to Use Anonymous Classes

1. When you need a one-time implementation of an interface or class.


2. For creating short-lived objects like event listeners, callbacks, or lightweight task-specific implementations.
3. To avoid creating a separate named class for simple use cases, making the code more concise.

Limitations of Anonymous Classes

1. Cannot have a constructor (but can initialize fields within the block).
2. Cannot explicitly extend a class and implement an interface simultaneously.
3. Cannot define static members (except static constants).

Functional Interfaces in Java


A functional interface in Java is an interface that contains exactly one abstract method. These interfaces are
the foundation for lambda expressions and method references introduced in Java 8. Functional interfaces
make it easier to write clean and concise code by enabling functional programming in Java.

Characteristics of Functional Interfaces

1. Single Abstract Method (SAM): Functional interfaces must have only one abstract method, which defines the
interface's functionality.
2. @FunctionalInterface Annotation: It is a marker annotation that explicitly declares an interface as functional. It
is optional but recommended as it prevents accidental addition of multiple abstract methods.
3. Default and Static Methods: Functional interfaces can include default and static methods without affecting
their functional nature since these are not abstract.
4. Compatible with Lambda Expressions: Functional interfaces are designed to work seamlessly with lambda
expressions.

Advantages of Functional Interfaces

1. Cleaner Code: Lambdas and functional interfaces reduce boilerplate code.


2. Readability: Simplified syntax makes code easier to read and maintain.
3. Compatibility: Works well with streams and collections in functional programming.

Java Heap Memory


The heap memory in Java is a portion of memory allocated to the Java Virtual Machine (JVM) for dynamic
memory allocation. It is where objects, instance variables, and class variables are stored during the execution of
a Java program. The heap is a critical part of the JVM's memory management system, and it is managed
automatically by the Garbage Collector (GC).

Key Features of Java Heap Memory

1. Dynamic Allocation:

 Objects are created and stored in the heap at runtime.


 Variables that are created using the new keyword are allocated memory in the heap.

2. Divided into Generations:


 Young Generation: Stores newly created objects. It is further divided into:
 Eden Space: Where all new objects are initially allocated.
 Survivor Spaces (S0 and S1): Used to store objects that survive a garbage collection cycle.
 Old Generation (Tenured Generation): Stores long-lived objects that have survived multiple garbage
collection cycles.
 Metaspace (introduced in Java 8): Stores class metadata, replacing the permanent generation.

3. Garbage Collection:

 The heap is managed by the garbage collector, which automatically reclaims memory by removing
objects that are no longer reachable.

4. Thread-Safe:

 The heap is shared among all threads in a Java application. Synchronization mechanisms are used to
ensure thread safety during access.

How Heap Memory Works

1. Object Creation :- When you create an object using the new keyword, the JVM allocates memory for it in the
heap.
2. Garbage Collection :- The JVM periodically performs garbage collection to free up memory occupied by
objects no longer in use, ensuring efficient memory utilization.
3. Out of Memory :- If the heap is full and garbage collection cannot free enough space, the JVM throws an
OutOfMemoryError.

Benefits of Heap Memory

 Dynamic Allocation: Allows the creation of objects at runtime.


 Automatic Management: Simplifies memory management with garbage collection.
 Scalable: Heap size can grow or shrink based on application needs.

Drawbacks of Heap Memory

 Slower Access: Accessing heap memory is slower compared to stack memory due to global sharing.
 Garbage Collection Overhead: Garbage collection may introduce performance overhead during cleanup.

Java Stack Memory


The stack memory in Java is a portion of memory allocated for each thread to store method call details, local
variables, and method execution order. It is used for managing the execution of threads and operates in a
Last-In-First-Out (LIFO) manner.

Key Features of Java Stack Memory

1. Thread-Specific :- Each thread has its own stack memory, independent of others.
2. Stores Method Information :- Includes details of active methods (method calls), local variables, and
references to objects in heap memory.
3. LIFO Structure :- Memory is allocated and deallocated in a Last-In-First-Out order, ensuring efficient
execution.
4. Limited Size :- Stack memory is smaller than heap memory and has a fixed size, configurable with JVM
options (e.g., -Xss).
5. No Garbage Collection :- Stack memory is automatically managed by the JVM. When a method completes, its
stack frame is removed, freeing up space.

Advantages of Stack Memory

1. Fast Access: Due to its LIFO structure, stack memory is faster than heap memory.
2. Thread Safety: Each thread has its own stack, eliminating the need for synchronization.
3. Automatic Memory Management: Memory is automatically freed when a method ends.

Disadvantages of Stack Memory

1. Limited Size: Stack memory is smaller and can lead to StackOverflowError if too many nested method calls
or recursion occur.
2. Temporary Storage: Data in the stack is temporary and only exists for the lifetime of the method.

Object Class in Java


The Object class is the root class of the Java class hierarchy. Every class in Java directly or indirectly inherits
from the Object class. It provides fundamental methods that are available to all Java objects, which can be
overridden to suit the needs of a specific class.

Key Features of the Object Class

1. Root of the Class Hierarchy :- All classes in Java are either a direct or indirect subclass of the Object class.
2. Universal Methods :- The Object class defines methods that every Java object inherits, such as toString(),
equals(), hashCode(), etc.
3. Supports Polymorphism :- A variable of type Object can refer to any object.

Commonly Used Methods in the Object Class

1. toString():
 Returns a string representation of the object.
 Default implementation: getClass().getName() + "@" + Integer.toHexString(hashCode()).
 Typically overridden to provide meaningful object details.

2. equals(Object obj):
 Checks if two objects are equal.
 Default implementation compares memory addresses.
 Should be overridden to compare object content.

3. hashCode():
 Returns a hash code value for the object.
 Must be overridden if equals() is overridden to ensure consistency.

4. clone():
 Creates a new object that is a copy of the current object.
 The class must implement Cloneable interface to use this method.

5. getClass() :- Returns the runtime class of the object.

6. finalize() :-
 Called by the garbage collector before reclaiming an object’s memory.
 Deprecated and rarely used in modern Java.

7. wait(), notify(), notifyAll() :- Used in thread communication for synchronization.

Polymorphism
Polymorphism is one of the key concepts of object-oriented programming, and it allows a single action to
behave differently based on the object or context. Java supports two types of polymorphism: Compile-time
polymorphism and Runtime polymorphism.

1. Compile-Time Polymorphism (Static Binding)

Compile-time polymorphism is achieved through method overloading. In this type, the method to be called is
resolved at compile time.

Key Characteristics:

 Binding at Compile Time: The compiler determines which method to invoke based on the method signature.
 Method Overloading: Occurs when two or more methods in the same class have the same name but different
parameter lists (number, type, or order of parameters).
 No Inheritance Required: Can exist within a single class.

Advantages:

 Improves code readability by allowing multiple methods with the same name but different functionality.
 Increases code flexibility.

2. Runtime Polymorphism (Dynamic Binding)


Runtime polymorphism is achieved through method overriding. In this type, the method to be called is
resolved at runtime, based on the object's actual type.

Key Characteristics:

 Binding at Runtime: The JVM determines which method to invoke based on the actual object type, not the
reference type.
 Method Overriding: Occurs when a subclass provides its specific implementation of a method defined in the
parent class.
 Inheritance Required: Involves a superclass and a subclass.

Advantages:

 Enables dynamic method dispatch, allowing behavior to change at runtime.


 Supports the Open-Closed Principle, where new behavior can be added without modifying existing code.

Exception Handling
An exception in Java is an unexpected event or error that occurs during the execution of a program and
disrupts its normal flow. Exceptions are Java's way of handling errors and other exceptional events in a
controlled and structured manner.

1. RuntimeException

 Category: It is an unchecked exception, meaning it is not checked at compile time.


 Definition: RuntimeException and its subclasses represent programming errors or exceptional conditions that
occur during the execution of the program, often caused by bugs or improper use of APIs.
 Handling Requirement: The compiler does not force you to handle RuntimeException. However, you can still
handle it using a try-catch block if needed.
 Common Causes:
 Invalid data manipulation (e.g., division by zero)
 Accessing invalid array indexes
 Calling methods on a null reference

Common Examples:

 NullPointerException
 ArrayIndexOutOfBoundsException
 ArithmeticException

2. IOException

 Category: It is a checked exception, meaning it must be either caught or declared in the method signature.
 Definition: IOException and its subclasses are used for handling input/output operations where exceptions may
occur, such as reading from a file, writing to a file, or working with network streams.
 Handling Requirement: You are required to handle IOException using a try-catch block or propagate it using
the throws keyword in the method declaration.
 Common Causes:
 File not found
 Unable to read or write a file
 Network communication failures
Common Examples:

 FileNotFoundException
 EOFException
 SocketException

Collection Framework in Java


The Java Collection Framework (JCF) provides a set of classes and interfaces to work with groups of objects
(collections). It includes data structures like lists, sets, maps, and utilities for manipulating data efficiently.

Key Features of the Collection Framework

1. Unified Architecture :- Provides a common structure for working with collections through interfaces,
implementations, and algorithms.
2. Type Safety :- With generics, collections ensure type safety, preventing runtime errors.
3. Dynamic Memory Allocation :- Collections can dynamically grow and shrink in size, unlike arrays.
4. Built-in Utility Methods :- Methods for sorting, searching, and manipulating data.
Advantages of the Collection Framework

1. Reusability :- Reusable data structures with ready-made implementations.


2. Performance :- Efficient algorithms for searching, sorting, and manipulating collections.
3. Consistency :- Unified API for all collection types.
4. Flexibility :- Supports dynamic data structures, unlike static arrays.

Disadvantages

1. Performance Overhead :- Some collection classes (e.g., LinkedList) may have higher memory or
processing requirements compared to arrays.
2. Complexity :- Overhead in learning the various classes and interfaces.

Collection Interface in Java


The Collection interface is the root interface of the Java Collection Framework, representing a group of
objects, known as elements. It provides standard methods for manipulating these elements, including adding,
removing, and iterating over them. It is part of the java.util package.

Java Queue Interface


The Queue interface in Java is part of the Collection Framework and represents a data structure that follows
the FIFO (First-In-First-Out) principle. Elements are added to the rear and removed from the front. It is part
of the java.util package and has various implementations, such as LinkedList, PriorityQueue, and ArrayDeque.
Array Dequeue
The ArrayDeque class in Java is a resizable array implementation of the Deque interface. It allows elements
to be added or removed from both ends (Double-Ended Queue). It is part of the java.util package and is often
used as a faster alternative to Stack, LinkedList, or other queue implementations.

Key Features of ArrayDeque

1. Dynamic Resizing :- The array automatically grows or shrinks as needed.


2. Efficient Operations :- Faster than LinkedList for stack and queue operations, as it avoids node creation
overhead.
3. No Null Elements :- Does not allow null values.
4. Thread-Safety :- It is not thread-safe, meaning it should not be used in concurrent environments without
external synchronization.
5. Implementation :- Backed by a resizable circular array for efficient memory utilization.
It is adviced to implement stack using ArrayDequeue.

 The Stack class in Java is a subclass of Vector, which is synchronized, making it slower for single-threaded
operations.
 ArrayDeque is not synchronized but provides faster operations in single-threaded scenarios, making it a better
choice for modern applications.

Set Interface in Java


The Set interface in Java is a part of the Collection Framework and represents a collection of unique
elements. It ensures that no duplicate values are present and is implemented by classes such as HashSet,
LinkedHashSet, and TreeSet. It is part of the java.util package.

Key Features of Set Interface


1. No Duplicates :- A Set does not allow duplicate elements.
2. Unordered Collection :- The elements in a Set are not stored in a specific order unless a specific
implementation like LinkedHashSet or TreeSet is used.
3. Allows One Null Element :- Most implementations allow at most one null element, except for
implementations like TreeSet, which may not allow null in sorted sets.

Advantages of Set Interface


1. Eliminates Duplicates :- Automatically handles uniqueness without additional checks.
2. Various Implementations :- Offers flexibility in terms of storage and retrieval order (HashSet,
LinkedHashSet, TreeSet).
3. Efficient Search :- Depending on the implementation, searching for an element can be very fast (e.g., O(1)
for HashSet).

Disadvantages of Set Interface


1. No Indexing :- Elements cannot be accessed by index, as Set does not maintain a positional order.
2. Limited Null Handling :- Some implementations (e.g., TreeSet) do not support null.

Classes That Implement the Set Interface


1. HashSet:
The HashSet class implements the Set interface using a hash table. It does not maintain any order of the
elements. Elements are stored based on their hash codes, making operations like add, remove, and search
efficient with an average time complexity of O(1). However, it does not allow duplicate elements and permits
one null element.
2. LinkedHashSet:
The LinkedHashSet is a subclass of HashSet that maintains the insertion order of elements. It uses a doubly
linked list to link elements in the order they were added. Like HashSet, it does not allow duplicates and permits
one null element, but it has slightly slower performance due to the overhead of maintaining the order.
3. TreeSet:
The TreeSet class implements the Set interface using a tree structure, specifically a Red-Black Tree. It stores
elements in their natural order (or based on a custom comparator provided during construction). It does not allow
duplicates or null elements. Operations like adding, removing, and searching elements have a time complexity of
O(log n).
4. EnumSet:
The EnumSet is a specialized Set implementation designed exclusively for use with enumeration (enum) types. It
is highly efficient as it internally uses a bit vector for storage. Elements are stored in the order defined by the
enumeration, and it does not allow null.

Map Interface in Java


The Map interface in Java is part of the Collection Framework and represents a data structure that maps keys
to values. It is a key-value pair collection where keys are unique, but values can be duplicated.

Key Features of the Map Interface

1. Key-Value Pair Storage :- Each entry in the map consists of a unique key and its associated value.
2. No Duplicate Keys :- A Map does not allow duplicate keys; if a duplicate key is added, the old value associated
with the key is replaced.
3. Null Handling :- Most implementations allow one null key and multiple null values (e.g., HashMap).
4. Implementations :- Common implementations include HashMap, LinkedHashMap, TreeMap, and
Hashtable.
Why do we need explicit conversion when working with the values of a Map?

When you want to store all values of a collection or map under a variable name, you often need
explicit conversion to transform the data into a specific format or type that can be handled more
conveniently. This process ensures compatibility and clarity.

1. Flexibility:
The values() method returns a Collection view, which is not a concrete implementation like List or
Set. If you want to perform operations specific to a List (like indexing) or Set (like ensuring
uniqueness), you need explicit conversion.
2. Specific Type Requirement:
If you pass values to a method that expects a specific type, such as List or Set, conversion is
necessary.
3. Immutability of View:
The Collection returned by values() is often a view tied to the original Map. Modifying it directly
may not be allowed or may impact the map, so a concrete copy is safer.

You might also like