0% found this document useful (0 votes)
22 views202 pages

Advance Java Module 1

The document outlines the curriculum for Advance Java Module 1, covering topics such as Java basics, control flow statements, object-oriented programming, exception handling, and Java 8 enhancements. It also includes practical steps for setting up Java IDEs like IntelliJ IDEA, Eclipse, and Visual Studio Code, along with examples of Java program structure and syntax. Key features of Java, including platform independence, robustness, and multithreading, are emphasized throughout the module.
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)
22 views202 pages

Advance Java Module 1

The document outlines the curriculum for Advance Java Module 1, covering topics such as Java basics, control flow statements, object-oriented programming, exception handling, and Java 8 enhancements. It also includes practical steps for setting up Java IDEs like IntelliJ IDEA, Eclipse, and Visual Studio Code, along with examples of Java program structure and syntax. Key features of Java, including platform independence, robustness, and multithreading, are emphasized throughout the module.
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

Advance Java – Module 1

1. Introduction to Java
1.1 Overview of Java and its Features
1.2 Java History and Evolution
1.3 JDK, JRE, and JVM (Differences & Roles)
1.4 Java Program Structure
1.5 Compilation & Execution Process
2. Java Basics
2.1 Java Syntax & Program Flow
2.2 Identifiers, Keywords, and Naming Conventions
2.3 Variables & Constants
2.4 Data Types (Primitive & Non-Primitive)
2.5 Type Casting & Type Conversion
2.6 Operators in Java (Arithmetic, Relational, Logical, Bitwise, Assignment, Unary, Ternary)
2.7 Expressions & Operator Precedence
2.8 Comments in Java (Single-line, Multi-line, Documentation)
3. Control Flow Statements
3.1 Decision-Making Statements (if, if-else, if-else-if, switch)
3.2 Looping Statements (for, while, do-while)
3.3 Enhanced for-loop
3.4 Jump Statements (break, continue, return)
3.5 Nested Loops and Labels
4. Arrays and Strings
4.1 Single-Dimensional Arrays
4.2 Multi-Dimensional Arrays
4.3 Array Operations (Copying, Sorting, Searching)
4.4 String Class and Methods
4.5 StringBuffer & StringBuilder
4.6 String Immutability & Interning
4.7 Common String Operations
Advance Java – Module 1

5. Methods in Java
5.1 Method Definition & Syntax
5.2 Parameter Passing (By Value vs. By Reference in Java)
5.3 Method Overloading
5.4 Recursion in Java
5.5 Varargs (Variable Arguments)
5.6 main() Method Deep Dive
6. Object-Oriented Programming (OOP)
6.1 Classes and Objects
6.2 Constructors & Constructor Overloading
6.3 this keyword
6.4 static keyword (Variables, Methods, Blocks)
6.5 Encapsulation & Access Modifiers
6.6 Inheritance (Single, Multilevel, Hierarchical)
6.7 super keyword
6.8 Method Overriding
6.9 Polymorphism (Compile-time & Runtime)
6.10 Abstraction (Abstract Class, Interface)
6.11 final keyword (Variables, Methods, Classes)
6.12 Nested & Inner Classes
7. Packages and Access Control
7.1 Creating and Using Packages
7.2 Access Modifiers Recap
7.3 Importing Classes & Static Imports
8. Exception Handling
8.1 Types of Exceptions (Checked, Unchecked, Errors)
8.2 try, catch, finally
8.3 Multiple Catch Blocks
8.4 Nested try-catch
Advance Java – Module 1

8.5 Throwing Exceptions (throw keyword)


8.6 Creating Custom Exceptions
8.7 throws keyword
8.8 Try-with-resources (Java 7+)
9. Java 8 Core Enhancements
9.1 Introduction to Java 8 Features
9.2 Lambda Expressions
9.3 Functional Interfaces (@FunctionalInterface)
9.4 Method References
9.5 Streams API (Creation, Intermediate & Terminal Operations)
9.6 forEach() Method
9.7 Default and Static Methods in Interfaces
9.8 Optional Class
9.9 New Date and Time API (java.time package)
10. Wrapper Classes and Autoboxing
10.1 Introduction to Wrapper Classes
10.2 Autoboxing & Unboxing
10.3 Utility Methods in Wrapper Classes
11. Java Memory Management
11.1 Stack & Heap Memory
11.2 Garbage Collection Overview
11.3 finalize() Method (Deprecated in Java 9)
12. Java I/O Basics
12.1 File Handling Introduction
12.2 Byte Streams vs. Character Streams
12.3 Reading & Writing Files
12.4 Buffered Streams
12.5 Serialization & Deserialization Basics
13. Multithreading Basics
Advance Java – Module 1

13.1 Thread Class & Runnable Interface


13.2 Thread Lifecycle
13.3 Thread Methods (start, sleep, join, interrupt)
13.4 Synchronization Basics
14. Miscellaneous Topics
14.1 Object Class Methods (toString, equals, hashCode, clone, getClass)
14.2 enum in Java
14.3 Annotations Basics
14.4 Command-Line Arguments

1. What Is Java?

Java is a high-level, object-oriented, class-based programming language designed to minimize


implementation dependencies. Originally developed by James Gosling and his team at Sun
Microsystems in the early 1990s (initially called "Oak," later renamed "Java"), it was publicly
released in 1996. Java’s hallmark is its “Write Once, Run Anywhere” (WORA) capability—thanks
to the JVM, the same bytecode runs identically across platforms

Key Features:

• Platform Independence: Source code compiles into bytecode (.class files), which the
JVM executes on any platform.

• Object-Oriented: Promotes modularity and code reusability using classes and objects.

• Robust & Secure: Provides exception handling, automatic memory management


(garbage collection), and runtime bytecode verification.

• Multithreading: Integrates thread support for concurrent programming.

• Dynamic Features: Supports dynamic class loading and interoperability across different
modules and versions.

2. JDK, JRE, and JVM

• JVM (Java Virtual Machine): The runtime environment that interprets or just-in-time
(JIT) compiles Java bytecode into machine-native code. It handles memory, executes
bytecode, and maintains security.
Advance Java – Module 1

• JRE (Java Runtime Environment): Includes the JVM and the standard Java class libraries.
It provides everything required to run Java applications but lacks development tools like
compilers.

• JDK (Java Development Kit): A full suite for developing Java applications. It includes the
JRE plus development tools like the Java compiler (javac), debugger, Javadoc generator,
etc.

Relationship: JDK includes JRE, which in turn contains the JVM.

3. Java Program Structure & Lifecycle

1. Source Code: Written in .java files, typically organized into packages.

2. Compilation: Use javac (part of JDK) to compile source code into .class bytecode files.

3. Execution: Run with java (JVM via JRE) which loads, verifies, and executes bytecode.

4. IDE Enhancements: Using an IDE simplifies coding, debugging, and project organization.

What is a Java IDE?

An IDE (Integrated Development Environment) is a software application that provides a


comprehensive set of tools for software development in one place. A Java IDE is specifically
designed to help developers write, compile, debug, and run Java programs efficiently.

Key Features of a Java IDE

Feature Description

Code Editor With syntax highlighting, code completion, and formatting

Compiler &
Built-in or configured to use JDK for compiling and running code
Runtime

Allows stepping through code, inspecting variables, and setting


Debugger
breakpoints

Project Explorer View and organize your project files and structure

Error Detection Real-time detection and hints for errors and warnings
Advance Java – Module 1

Feature Description

Build Tool Support Supports Maven, Gradle, Ant, etc.

Version Control Git integration for tracking changes and collaboration

Plugin Support Extend IDE functionality with plugins (e.g., for Spring, JavaFX, Android)

Summary Comparison

Step IntelliJ IDEA Eclipse IDE

JDK Installation Required first, verify with java -version Same

Download & Install IDE JetBrains site (Community Edition) eclipse.org (Java Developers pack)

Welcome → New Project → configure


New Project File → New Java Project
JDK

Create Class Right-click src → New → Java Class Same

Write & Run Code Write and press ▶ Write, then Run (menu or Ctrl+F11)

Plugins & Learning Tools IDE Features Trainer plugin Use Eclipse Marketplace for plugins

1. IntelliJ IDEA (Community Edition) – Step-by-Step Setup

Step 1: Install Java JDK

1. Download the latest JDK:

o Oracle JDK

o OpenJDK
Advance Java – Module 1

2. Install it.

3. Set environment variable JAVA_HOME (optional but helpful).

Step 2: Install IntelliJ IDEA

1. Go to https://www.jetbrains.com/idea/download

2. Choose Community Edition (Free).

3. Download and install.

Step 3: Create a New Java Project

1. Open IntelliJ → Click New Project

2. Select Java from the left.

3. Under Project SDK, click Add SDK and point to your installed JDK.

4. Click Next → Select Create project from template (optional) → Click Next

5. Name your project → Click Finish

Step 4: Create a Java Class

1. Right-click src folder → New → Java Class

2. Name it HelloWorld

3. Write the following code:

java

public class HelloWorld {

public static void main(String[] args) {

System.out.println("Hello from IntelliJ!");

}
Advance Java – Module 1

Step 5: Run the Program

• Right-click the file → Click Run 'HelloWorld'

• Or click the green triangle beside main().

2. Eclipse IDE – Step-by-Step Setup

Step 1: Install Java JDK

1. Download from https://www.oracle.com/java/technologies/javase-downloads.html

2. Install it.

Step 2: Download Eclipse

1. Go to https://www.eclipse.org/downloads/

2. Download Eclipse IDE for Java Developers

3. Run the installer and choose Java Development Tools package.

4. Launch Eclipse.

Step 3: Create a New Java Project

1. File → New → Java Project

2. Enter project name (e.g., MyFirstProject)

3. Click Finish

Step 4: Create a Java Class

1. Right-click on src → New → Class

2. Enter HelloWorld as the class name


Advance Java – Module 1

3. Check the checkbox for public static void main(String[] args)

4. Click Finish

Step 5: Write and Run Code

Replace or add the following code if needed:

java

public class HelloWorld {

public static void main(String[] args) {

System.out.println("Hello from Eclipse!");

Run the program:

• Right-click file → Run As → Java Application

• Or click the green "Run" icon in the toolbar.

3. Visual Studio Code (VS Code) – Step-by-Step Setup

Step 1: Install Java JDK

1. Download and install JDK:

o Oracle

o OpenJDK

2. Confirm installation: run java -version in terminal/command prompt.

Step 2: Install VS Code

1. Download from https://code.visualstudio.com/


Advance Java – Module 1

2. Install and launch it.

Step 3: Install Java Extensions

1. Open Extensions panel (Ctrl+Shift+X)

2. Search for and install:

o "Extension Pack for Java" (by Microsoft)

▪ Includes: Language support, debugger, project manager, and test runner.

Step 4: Create Java Project

Option 1: Quick Start

1. Press Ctrl+Shift+P → Type: Java: Create Java Project

2. Choose No Build Tools

3. Choose location and name your project.

Option 2: Manual

1. Create a folder and a file HelloWorld.java

2. Open the folder in VS Code.

Step 5: Write Java Code

In HelloWorld.java:

public class HelloWorld {

public static void main(String[] args) {

System.out.println("Hello from VS Code!");

Step 6: Run Java Program

• Click Run button (play icon at top-right)


Advance Java – Module 1

• Or right-click file → Run Java

2. Java Basics

Java Syntax & Program Flow

1. Definition

Java Syntax refers to the set of rules and conventions that define how Java code must be
written and structured so that the compiler can understand and execute it.
It covers keywords, data types, operators, statements, blocks, class/method definitions, and
naming rules.

Program Flow in Java refers to the sequence in which the instructions/statements are executed
— from starting a program to producing the final output.

2. Basic Structure of a Java Program

Every Java program follows a standard structure:

/*

Documentation Comment (Optional) – explains the program

*/

package packageName; // Optional

import java.util.*; // Optional imports

public class ClassName { // Class declaration

public static void main(String[] args) { // Main method

// Statements

}
Advance Java – Module 1

3. Components of Java Syntax

3.1 Comments

• Single-line: // comment

• Multi-line: /* comment */

• Documentation: /** comment */ (used with Javadoc)

3.2 Class Declaration

• Java code must be inside a class (except package/module declarations).

• Class names follow PascalCase naming convention.

3.3 main() Method

• Entry point of the program.

• Syntax:

public static void main(String[] args) { }

• public → accessible by JVM.

• static → no need to create an object to run.

• void → no return value.

• String[] args → stores command-line arguments.

3.4 Statements

• Instructions executed by JVM.

• End with a semicolon ;.

3.5 Blocks

• Group of statements enclosed in { }.

3.6 Identifiers & Keywords

• Identifiers: Names for variables, methods, classes, etc.

• Keywords: Reserved words like class, public, int.


Advance Java – Module 1

4. Java Program Flow

A Java program execution goes through these steps:

1. Write the Source Code → .java file.

2. Compile the Code → javac ProgramName.java

o Compiler checks syntax and generates .class file (bytecode).

3. Run the Program → java ProgramName

o JVM loads bytecode, interprets, and executes instructions.

Flow Diagram:

Source Code (.java)

↓ javac

Bytecode (.class)

↓ java

Execution by JVM

5. How Java Syntax Works

• Strict typing: Every variable must have a data type.

• Case-sensitive: Main and main are different.

• Class name = File name (if public class).

• One public class per file.

• Indentation & formatting → not mandatory for execution but improves readability.

• Blocks define scope → Variables declared inside a block can’t be accessed outside it.

6. Example Code

// This is a sample Java program

public class HelloWorld {


Advance Java – Module 1

public static void main(String[] args) {

// Printing message to the console

System.out.println("Hello, Java Syntax and Program Flow!");

7. Output

Hello, Java Syntax and Program Flow!

8. Step-by-Step Execution

1. Save file as HelloWorld.java.

2. Open terminal and compile:

javac HelloWorld.java

→ Generates HelloWorld.class.

3. Run the program:

java HelloWorld

→ JVM executes main() method and prints the output.

9. Key Points to Remember

• File name must match the public class name.

• main() method is the execution entry point.

• Java is compiled + interpreted (Bytecode + JVM).

• Use proper indentation for readability.

• Follow naming conventions for identifiers.


Advance Java – Module 1

Identifiers, Keywords, and Naming Conventions in Java

1. Definition

• Identifiers → Names given to elements like classes, variables, methods, objects,


packages, etc. They are user-defined names.

• Keywords → Predefined, reserved words in Java with special meaning for the compiler.
Cannot be used as identifiers.

• Naming Conventions → Standard rules & best practices for naming identifiers to make
code readable and maintainable.

2. Identifiers in Java

Rules for Identifiers

1. Can contain letters (A–Z, a–z), digits (0–9), underscore (_), and dollar sign ($).

2. Must start with a letter, _, or $ (cannot start with a digit).

3. Case-sensitive → myVar and myvar are different.

4. Cannot use Java keywords.

5. No special characters like @, #, %, &.

Valid Identifiers:

myVariable

_data

$amount

num1

MAX_VALUE

Invalid Identifiers:

1value // starts with a number

class // keyword

my-variable // contains hyphen


Advance Java – Module 1

3. Keywords in Java

Java has 50+ reserved words (in Java 8).


They are all lowercase.

List of Java Keywords

Category Keywords

Access Control public, private, protected

Class/Interface class, interface, enum

Method/Variable static, final, abstract, synchronized, volatile


Control

Object/Instance new, this, super, instanceof

Flow Control if, else, switch, case, default, while, do, for, break, continue, return

Exception Handling try, catch, finally, throw, throws

Primitive Types byte, short, int, long, float, double, char, boolean, void

Others package, import, extends, implements, goto (unused), const (unused),


native, strictfp, assert

4. Naming Conventions in Java

Java follows CamelCase style and industry naming guidelines.

Element Convention Example

Class PascalCase StudentDetails, BankAccount

Interface PascalCase Runnable, Comparable

Method camelCase calculateTotal(), getName()

Variable camelCase totalMarks, studentName

Constant UPPER_CASE MAX_SPEED, PI

Package lowercase java.util, com.mycompany


Advance Java – Module 1

5. How It Works

• The compiler strictly checks keywords and identifiers.

• If an identifier is the same as a keyword → Compile-time Error.

• Naming conventions don’t affect compilation, but following them improves readability
and maintainability.

6. Example Code

public class NamingExample {

// Constant

static final int MAX_SPEED = 120;

// Variable

int currentSpeed = 60;

// Method

public void increaseSpeed(int increment) {

currentSpeed += increment;

public static void main(String[] args) {

NamingExample car = new NamingExample();

car.increaseSpeed(20);

System.out.println("Current Speed: " + car.currentSpeed);

System.out.println("Max Speed: " + MAX_SPEED);

}
Advance Java – Module 1

7. Output

Current Speed: 80

Max Speed: 120

8. Key Points to Remember

• Identifiers are case-sensitive and must follow rules.

• Keywords are reserved; they can’t be used as variable names.

• Always follow naming conventions for clean, professional code.

Variables and Constants in Java

1. Definition

A variable in Java is a named memory location that stores data, whose value can change during
program execution.
A constant is a fixed value that does not change once assigned. In Java, constants are usually
declared using the final keyword.

2. Variable Types

Java variables are categorized into three main types:

1. Local Variables

o Declared inside methods, constructors, or blocks.

o Created when the method is called and destroyed after execution.

o Must be initialized before use.

2. Instance Variables

o Declared inside a class but outside any method.

o Each object gets its own copy.


Advance Java – Module 1

o Created when an object is created, destroyed when the object is destroyed.

3. Static Variables (Class Variables)

o Declared with the static keyword inside a class.

o Shared among all objects of the class.

o Created when the class is loaded, destroyed when the program ends.

3. Constant Declaration

• Declared using the final keyword.

• Once assigned, the value cannot be changed.

• By convention, constant names are written in UPPERCASE.

Example:

static final double PI = 3.14159;

4. Syntax

Variable Declaration

dataType variableName; // Declaration

dataType variableName = value; // Declaration + Initialization

Example:

int age;

int marks = 85;

Constant Declaration

final dataType CONSTANT_NAME = value;

Example:

final int MAX_STUDENTS = 100;

5. How It Works
Advance Java – Module 1

When a variable is declared, memory is allocated to store its value based on its data type.
Local variables are stored in the stack memory, while instance and static variables are stored in
the heap memory.
Constants are stored in a fixed memory location and cannot be reassigned once initialized.

6. Example Code

public class VariableExample {

// Instance variable

int rollNumber = 101;

// Static variable

static String collegeName = "ABC University";

// Constant

static final double PI = 3.14159;

public void displayDetails() {

// Local variable

String studentName = "John";

System.out.println("Name: " + studentName);

System.out.println("Roll Number: " + rollNumber);

System.out.println("College: " + collegeName);

System.out.println("PI Value: " + PI);

public static void main(String[] args) {


Advance Java – Module 1

VariableExample obj = new VariableExample();

obj.displayDetails();

7. Output

Name: John

Roll Number: 101

College: ABC University

PI Value: 3.14159

8. Key Points to Remember

• Variable names must follow identifier rules.

• Local variables must be initialized before use.

• static variables are shared across all instances.

• Constants are declared with final and cannot be modified.

Data Types in Java

1. Definition

A data type in Java defines the kind of data a variable can store, how much memory it will take,
and what operations can be performed on it.
Java is a strongly typed language, meaning every variable must have a declared data type
before it can be used.

2. Types of Data Types

Java data types are mainly divided into two categories:

2.1 Primitive Data Types


Advance Java – Module 1

These are the basic built-in data types in Java. They store simple values, not objects.
There are 8 primitive types:

Data Type Size (bytes) Default Value Range

byte 1 0 -128 to 127

short 2 0 -32,768 to 32,767

int 4 0 -2,147,483,648 to 2,147,483,647

long 8 0L -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

float 4 0.0f ~6–7 decimal digits

double 8 0.0d ~15 decimal digits

char 2 '\u0000' 0 to 65,535 (Unicode)

boolean 1 bit false true or false

2.2 Non-Primitive (Reference) Data Types

These store references (addresses) to objects, not the actual values. Examples:

• Strings (String name = "Java";)

• Arrays (int[] arr = {1, 2, 3};)

• Classes (user-defined types)

• Interfaces

• Enums

3. Syntax

Primitive Type Example

int age = 25;

double salary = 50000.50;

boolean isActive = true;


Advance Java – Module 1

Non-Primitive Type Example

String name = "John";

int[] marks = {85, 90, 78};

4. How It Works

• Primitive types store the actual value in memory.

• Reference types store the memory address of the object.

• JVM allocates memory for variables depending on their data type.

• Default values are assigned to instance and static variables, but local variables must be
initialized before use.

5. Example Code

public class DataTypeExample {

// Primitive types

byte b = 10;

int num = 100;

double price = 99.99;

char grade = 'A';

boolean status = true;

// Non-primitive types

String name = "Alice";

int[] scores = {85, 90, 78};

public void display() {

System.out.println("Byte value: " + b);


Advance Java – Module 1

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

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

System.out.println("Char value: " + grade);

System.out.println("Boolean value: " + status);

System.out.println("String value: " + name);

System.out.print("Array values: ");

for (int score : scores) {

System.out.print(score + " ");

public static void main(String[] args) {

DataTypeExample obj = new DataTypeExample();

obj.display();

6. Output

Byte value: 10

Integer value: 100

Double value: 99.99

Char value: A

Boolean value: true

String value: Alice

Array values: 85 90 78
Advance Java – Module 1

7. Key Points to Remember

• Java has 8 primitive types; all others are reference types.

• Primitive types store actual values; reference types store memory addresses.

• Local variables have no default values — must be initialized.

• Data type determines memory size and range.

1. Arithmetic Operators

Definition

Arithmetic operators are used to perform basic mathematical operations on numeric data
types (int, float, double, etc.).

Operators List

Operator Meaning
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulus (remainder)

How it Works

• Takes two operands and performs the specified mathematical operation.

• Division between integers returns an integer result.

• % gives the remainder of a division.

Syntax

result = operand1 operator operand2;

Example

public class ArithmeticExample {

public static void main(String[] args) {


Advance Java – Module 1

int a = 10, b = 3;

System.out.println("Addition: " + (a + b));

System.out.println("Subtraction: " + (a - b));

System.out.println("Multiplication: " + (a * b));

System.out.println("Division: " + (a / b));

System.out.println("Modulus: " + (a % b));

Output

Addition: 13

Subtraction: 7

Multiplication: 30

Division: 3

Modulus: 1

2. Unary Operators

Definition

Unary operators work on a single operand to perform operations like increment, decrement,
negation, or logical NOT.

Types of Unary Operators in Java

Operator Meaning Example


+ Unary plus (positive value, usually redundant) +a
- Unary minus (negates value) -a
++ Increment (increases value by 1) ++a or a++
-- Decrement (decreases value by 1) --a or a--
Advance Java – Module 1

! Logical NOT (reverses boolean value) !false

How it Works

• Unary Plus (+) → Mostly unused because positive numbers are default.

• Unary Minus (-) → Converts positive to negative and vice versa.

• Increment (++) → Adds 1 to the operand.

o Pre-increment (++a) → Increases first, then uses the value.

o Post-increment (a++) → Uses the value first, then increases.

• Decrement (--) → Subtracts 1 from the operand.

o Pre-decrement (--a) → Decreases first, then uses the value.

o Post-decrement (a--) → Uses the value first, then decreases.

• Logical NOT (!) → Flips boolean values: true → false, false → true.

Syntax

++variable;

variable++;

--variable;

variable--;

-variable;

!booleanValue;

Example

public class UnaryExample {

public static void main(String[] args) {

int x = 5;

boolean flag = true;


Advance Java – Module 1

System.out.println("Original x: " + x);

// Pre-increment

System.out.println("++x: " + (++x)); // increments before printing

// Post-increment

System.out.println("x++: " + (x++)); // prints first, then increments

// Pre-decrement

System.out.println("--x: " + (--x)); // decrements before printing

// Post-decrement

System.out.println("x--: " + (x--)); // prints first, then decrements

// Unary minus

System.out.println("Unary minus of x: " + (-x));

// Logical NOT

System.out.println("Logical NOT of flag: " + (!flag));

Output

Original x: 5

++x: 6
Advance Java – Module 1

x++: 6

--x: 6

x--: 6

Unary minus of x: -5

Logical NOT of flag: false

3. Assignment Operators

Definition
Assignment operators are used to assign values to variables. The simplest is =, but Java also
provides compound assignment operators to perform an operation and assignment in one step.

Types of Assignment Operators

Operator Meaning Example Equivalent to


= Assigns right-hand value to left-hand variable x = 5; —
+= Adds right-hand value to left-hand variable x += 3; x = x + 3;
-= Subtracts right-hand value from left-hand variable x -= 3; x = x - 3;
*= Multiplies left-hand variable by right-hand value x *= 3; x = x * 3;
/= Divides left-hand variable by right-hand value x /= 3; x = x / 3;
%= Stores remainder in left-hand variable x %= 3; x = x % 3;

How it Works
The left-hand operand is updated with the result of applying the operator with the right-hand
operand. Compound operators reduce code repetition.

Syntax

variable = value;

variable operator= value;

Example

public class AssignmentExample {


Advance Java – Module 1

public static void main(String[] args) {

int a = 10;

System.out.println("Initial a: " + a);

a += 5;

System.out.println("After a += 5: " + a);

a -= 3;

System.out.println("After a -= 3: " + a);

a *= 2;

System.out.println("After a *= 2: " + a);

a /= 4;

System.out.println("After a /= 4: " + a);

a %= 3;

System.out.println("After a %= 3: " + a);

Output

Initial a: 10

After a += 5: 15

After a -= 3: 12

After a *= 2: 24
Advance Java – Module 1

After a /= 4: 6

After a %= 3: 0

4. Relational Operators

Definition
Relational operators are used to compare two values. They return a boolean result (true or
false) depending on the comparison outcome.

Types of Relational Operators

Operator Meaning Example Result

== Equal to 5 == 5 true

!= Not equal to 5 != 3 true

> Greater than 7>5 true

< Less than 3<5 true

>= Greater than or equal to 5 >= 5 true

<= Less than or equal to 4 <= 6 true

How it Works

• Compares left operand with right operand.

• Returns true if the comparison is correct, otherwise returns false.

• Commonly used in conditions like if, while, for.

Syntax

boolean result = (operand1 operator operand2);

Example

public class RelationalExample {

public static void main(String[] args) {


Advance Java – Module 1

int x = 10, y = 20;

System.out.println("x == y: " + (x == y));

System.out.println("x != y: " + (x != y));

System.out.println("x > y: " + (x > y));

System.out.println("x < y: " + (x < y));

System.out.println("x >= y: " + (x >= y));

System.out.println("x <= y: " + (x <= y));

Output

x == y: false

x != y: true

x > y: false

x < y: true

x >= y: false

x <= y: true

5. Logical Operators

Definition
Logical operators are used to combine multiple boolean expressions or values, producing a
boolean result (true or false).

Types of Logical Operators

Operator Meaning Example Result

&& Logical AND → true if both (x > 5 && y < true only if both conditions
operands are true 10) are true
Advance Java – Module 1

|| Logical OR → true if at least one (x > 5 || y < true if any condition is true
operand is true 10)

! Logical NOT → reverses boolean !(x > 5) true if x > 5 is false


value

How it Works

• AND (&&) → All conditions must be true for the result to be true.

• OR (||) → At least one condition must be true for the result to be true.

• NOT (!) → Inverts the truth value of a boolean expression.

Syntax

boolean result = condition1 && condition2;

boolean result = condition1 || condition2;

boolean result = !condition;

Example

public class LogicalExample {

public static void main(String[] args) {

int x = 8, y = 5;

System.out.println("(x > 5 && y < 10): " + (x > 5 && y < 10));

System.out.println("(x > 5 && y > 10): " + (x > 5 && y > 10));

System.out.println("(x > 5 || y > 10): " + (x > 5 || y > 10));

System.out.println("(x < 5 || y < 10): " + (x < 5 || y < 10));

System.out.println("!(x > 5): " + !(x > 5));

}
Advance Java – Module 1

Output

(x > 5 && y < 10): true

(x > 5 && y > 10): false

(x > 5 || y > 10): true

(x < 5 || y < 10): true

!(x > 5): false

6. Bitwise Operators

Definition
Bitwise operators perform operations directly on binary representations of integer types (byte,
short, int, long, and char). They work at the bit level, unlike logical operators which work with
boolean values.

Types of Bitwise Operators

Operator Meaning Example Result (Binary) Result (Decimal)

& Bitwise AND 5&3 0101 & 0011 = 0001 1

| Bitwise OR 5|3 0101 | 0011 = 0111 7

^ Bitwise XOR 5^3 0101 ^ 0011 = 0110 6

~ Bitwise Complement ~5 ~00000101 = 11111010 -6 (2’s


complement)

<< Left Shift 5 << 1 00000101 << 1 = 10


00001010

>> Right Shift (sign- 5 >> 1 00000101 >> 1 = 2


preserving) 00000010

>>> Unsigned Right Shift -5 >>> 1 Shifts right with zero fill Large positive value

How it Works

• & → Only 1 if both bits are 1.

• | → 1 if at least one bit is 1.

• ^ → 1 if bits are different.


Advance Java – Module 1

• ~ → Inverts every bit (1 → 0, 0 → 1).

• << → Shifts bits to the left, filling with zeros.

• >> → Shifts bits right, preserving the sign bit (keeps negative numbers negative).

• >>> → Shifts bits right, filling with zeros (ignores sign bit).

Syntax

result = operand1 & operand2;

result = operand1 | operand2;

result = operand1 ^ operand2;

result = ~operand;

result = operand << positions;

result = operand >> positions;

result = operand >>> positions;

Example

public class BitwiseExample {

public static void main(String[] args) {

int a = 5; // Binary: 0101

int b = 3; // Binary: 0011

System.out.println("a & b: " + (a & b));

System.out.println("a | b: " + (a | b));

System.out.println("a ^ b: " + (a ^ b));

System.out.println("~a: " + (~a));

System.out.println("a << 1: " + (a << 1));

System.out.println("a >> 1: " + (a >> 1));

System.out.println("-a >>> 1: " + (-a >>> 1));

}
Advance Java – Module 1

Output

a & b: 1

a | b: 7

a ^ b: 6

~a: -6

a << 1: 10

a >> 1: 2

-a >>> 1: 2147483645

7. Ternary Operator

Definition
The ternary operator (?:) is a conditional operator that evaluates a boolean expression and
returns one of two values depending on whether the expression is true or false.

How it Works

• If the condition is true, the first value is returned.

• If the condition is false, the second value is returned.

Syntax

variable = (condition) ? valueIfTrue : valueIfFalse;

Example

public class TernaryExample {

public static void main(String[] args) {

int a = 10, b = 20;

String result = (a > b) ? "a is greater" : "b is greater";

System.out.println(result);
Advance Java – Module 1

int max = (a > b) ? a : b;

System.out.println("Max value: " + max);

Output

b is greater

Max value: 20

Key Points

• The ternary operator is the only operator in Java that takes three operands.

• It’s a concise replacement for small if-else statements but should be avoided for complex
logic for readability.

8. Type Cast Operators

Definition
Type casting operators are used to convert a variable from one data type to another. In Java,
this can be done implicitly (widening) or explicitly (narrowing).

Types of Casting

Type Description Example

Widening Smaller type → Larger type (no data loss, done int → long, float →
(Implicit) automatically) double

Narrowing Larger type → Smaller type (possible data loss, double → int, long
(Explicit) must be done manually) → byte

How it Works

• Widening: Java automatically converts if no risk of losing data.

• Narrowing: You must use a cast operator (type) because data might be lost.

Syntax

// Widening
Advance Java – Module 1

largerTypeVar = smallerTypeVar;

// Narrowing

smallerTypeVar = (smallerType) largerTypeVar;

Example

public class TypeCastExample {

public static void main(String[] args) {

// Widening (Automatic)

int intVal = 100;

double doubleVal = intVal; // int → double

System.out.println("Widening: " + doubleVal);

// Narrowing (Manual)

double pi = 3.14159;

int intPi = (int) pi; // double → int

System.out.println("Narrowing: " + intPi);

// Narrowing with data loss

int largeNum = 260;

byte smallNum = (byte) largeNum; // int → byte (data loss)

System.out.println("Data loss example: " + smallNum);

Output

Widening: 100.0

Narrowing: 3
Advance Java – Module 1

Data loss example: 4

Key Points

• Widening is safe and automatic.

• Narrowing may lose precision or data and must be done explicitly.

• Casting between incompatible types (like String to int) requires parsing, not type casting.

9. Expressions in Java

Definition
An expression in Java is a combination of variables, constants, operators, and method calls that
produces a single value.

How it Works

• An expression is evaluated by the Java compiler to produce a result.

• The type of the result depends on the components and operators used.

• Every expression has:

o Operands (values or variables)

o Operators (symbols like +, *, &&, ? :)

o Result (evaluated value)

Types of Expressions

Type Example Result

Arithmetic Expression 5+3*2 11

Relational Expression a>b true / false

Logical Expression (a > b) && (c < d) true / false

Assignment Expression x = 10 10

Ternary Expression (a > b) ? a : b One of the two values

Method Call Expression Math.sqrt(16) 4.0

Syntax
Advance Java – Module 1

result = operand1 operator operand2;

boolean isTrue = (a > b) && (c < d);

Example

public class ExpressionExample {

public static void main(String[] args) {

int a = 5, b = 3, c = 10;

// Arithmetic Expression

int sum = a + b * c; // precedence: * before +

System.out.println("Arithmetic Expression: " + sum);

// Relational Expression

boolean isGreater = a > b;

System.out.println("Relational Expression: " + isGreater);

// Logical Expression

boolean logic = (a > b) && (c > a);

System.out.println("Logical Expression: " + logic);

// Ternary Expression

int max = (a > c) ? a : c;

System.out.println("Ternary Expression (Max): " + max);

// Assignment Expression

int x;

System.out.println("Assignment Expression: " + (x = 100));


Advance Java – Module 1

// Method Call Expression

double squareRoot = Math.sqrt(81);

System.out.println("Method Call Expression: " + squareRoot);

Output

Arithmetic Expression: 35

Relational Expression: true

Logical Expression: true

Ternary Expression (Max): 10

Assignment Expression: 100

Method Call Expression: 9.0

Key Points to Remember

• An expression always produces a value.

• Operator precedence and associativity matter in how expressions are evaluated.

• Use parentheses () to make expressions clearer and avoid precedence confusion.

Control Statements in Java


Control statements in Java are instructions that determine the flow of execution in a program.
They allow conditional execution, looping, and branching based on certain conditions.

Types of Control Statements

1. Decision-Making Statements (if, if-else, if-else-if, nested if, switch)

2. Looping Statements (for, while, do-while, for-each)

3. Branching Statements (break, continue, return)


Advance Java – Module 1

1. if Statement
Definition: Executes a block of code only if the given condition is true.
Syntax:

if (condition) {

// statements to execute if condition is true

How it works: The condition inside parentheses is evaluated. If it is true, the block executes;
otherwise, it is skipped.
Example:

public class IfExample {

public static void main(String[] args) {

int number = 10;

if (number > 5) {

System.out.println("Number is greater than 5");

Output:

Number is greater than 5

2. if-else Statement
Definition: Executes one block if the condition is true, otherwise executes another block.
Syntax:

if (condition) {

// executed if true

} else {

// executed if false

}
Advance Java – Module 1

How it works: If the condition is true, the first block executes; if false, the else block executes.
Example:

public class IfElseExample {

public static void main(String[] args) {

int number = 3;

if (number > 5) {

System.out.println("Number is greater than 5");

} else {

System.out.println("Number is 5 or less");

Output:

Number is 5 or less

3. if-else-if Ladder
Definition: Used to check multiple conditions sequentially.
Syntax:

if (condition1) {

// executed if condition1 is true

} else if (condition2) {

// executed if condition2 is true

} else {

// executed if none are true

}
Advance Java – Module 1

How it works: Conditions are evaluated from top to bottom. The first condition that evaluates
to true executes its block, and remaining conditions are skipped.

Example:

public class IfElseIfExample {

public static void main(String[] args) {

int marks = 85;

if (marks >= 90) {

System.out.println("Grade A+");

} else if (marks >= 75) {

System.out.println("Grade A");

} else {

System.out.println("Grade B");

Output:

Grade A

4. Nested if Statement
Definition: An if statement inside another if statement.
Syntax:

java

if (condition1) {

if (condition2) {

// executed if both are true


Advance Java – Module 1

How it works: The outer condition is evaluated first; if true, the inner condition is checked.

Example:

public class NestedIfExample {

public static void main(String[] args) {

int age = 20;

int weight = 65;

if (age >= 18) {

if (weight > 50) {

System.out.println("Eligible to donate blood");

Output:

Eligible to donate blood

5. Switch Statement in Java

Definition
The switch statement is a multi-way branch statement that allows a variable to be tested against
a list of values, each associated with a case. It is an alternative to the if-else-if ladder when
checking for equality against multiple constant values.

How it Works

1. The switch expression is evaluated once.


Advance Java – Module 1

2. The result is compared with each case value.

3. If a match is found, the corresponding block is executed.

4. The break statement is used to exit the switch after executing the matched case.

5. If no match is found, the default block is executed (optional).

Syntax

switch (expression) {

case value1:

// code block

break;

case value2:

// code block

break;

...

default:

// code block

Example

public class SwitchExample {

public static void main(String[] args) {

int day = 3;

String dayName;

switch (day) {

case 1:

dayName = "Monday";

break;
Advance Java – Module 1

case 2:

dayName = "Tuesday";

break;

case 3:

dayName = "Wednesday";

break;

case 4:

dayName = "Thursday";

break;

case 5:

dayName = "Friday";

break;

case 6:

dayName = "Saturday";

break;

case 7:

dayName = "Sunday";

break;

default:

dayName = "Invalid day";

System.out.println("Day: " + dayName);

Output
Advance Java – Module 1

Day: Wednesday

For Loop in Java

Definition
The for loop in Java is an entry-controlled looping statement that executes a block of code
repeatedly for a known number of iterations. It is often used when you know in advance how
many times you want to execute a statement or block of statements.

How it Works

1. Initialization: Runs only once at the start; used to initialize loop control variables.

2. Condition: Checked before each iteration; if true, the loop body executes; if false, the
loop terminates.

3. Update: Executed after each iteration; used to change the loop control variable.

Syntax

for (initialization; condition; update) {

// code to be executed

Example

public class ForLoopExample {

public static void main(String[] args) {

for (int i = 1; i <= 5; i++) {

System.out.println("Iteration: " + i);

Output

Iteration: 1

Iteration: 2
Advance Java – Module 1

Iteration: 3

Iteration: 4

Iteration: 5

While Loop in Java

Definition
The while loop in Java is an entry-controlled loop that repeatedly executes a block of code as
long as a given condition evaluates to true. It is generally used when the number of iterations is
not known beforehand and depends on a condition being met during execution.

How it Works

1. Condition Check: Before each iteration, the loop evaluates the condition.

2. Execution: If the condition is true, the loop body executes.

3. Re-evaluation: After executing the body, the condition is checked again.

4. Termination: When the condition becomes false, the loop ends.

Syntax

while (condition) {

// code to be executed

Example

public class WhileLoopExample {

public static void main(String[] args) {

int count = 1;

while (count <= 5) {

System.out.println("Count: " + count);

count++;

}
Advance Java – Module 1

Output

Count: 1

Count: 2

Count: 3

Count: 4

Count: 5

Do-While Loop in Java

Definition
The do-while loop in Java is an exit-controlled loop that executes a block of code at least once,
and then repeatedly executes it as long as the given condition evaluates to true. Unlike the
while loop, the condition is checked after the loop body is executed.

How it Works

1. Execution First: The loop body executes once before any condition check.

2. Condition Check: After execution, the condition is evaluated.

3. Repeat or Terminate: If the condition is true, the loop body executes again. If false, the
loop ends.

Syntax

do {

// code to be executed

} while (condition);

Example

public class DoWhileExample {

public static void main(String[] args) {

int count = 1;
Advance Java – Module 1

do {

System.out.println("Count: " + count);

count++;

} while (count <= 5);

Output

Count: 1

Count: 2

Count: 3

Count: 4

Count: 5

Enhanced For Loop (For-Each) in Java

Definition
The enhanced for loop, also known as the for-each loop, is used to iterate over arrays or
collections without using an explicit counter. It automatically iterates through all elements in a
sequence, providing a simpler and more readable approach when you don’t need to know the
index.

How it Works

1. The loop picks each element from the collection or array one by one.

2. The variable in the loop temporarily stores the current element for use inside the loop
body.

3. The process repeats until all elements have been processed.

Syntax

for (datatype variable : array_or_collection) {

// code to be executed
Advance Java – Module 1

Example

public class EnhancedForLoopExample {

public static void main(String[] args) {

String[] fruits = {"Apple", "Banana", "Cherry"};

for (String fruit : fruits) {

System.out.println("Fruit: " + fruit);

Output

Fruit: Apple

Fruit: Banana

Fruit: Cherry

Break Statement in Java

Definition
The break statement is used to terminate a loop or switch statement immediately, regardless of
whether the loop’s condition has been met or not. Control is transferred to the statement
immediately following the loop or switch.

How it Works

1. When the break statement is encountered inside a loop or switch, program control
jumps out of that structure.

2. It is often used when a certain condition is met and there’s no need to continue further
iterations.

Syntax

break;
Advance Java – Module 1

Continue Statement in Java

Definition
The continue statement is used in loops to skip the current iteration and move control to the
next iteration of the loop. Unlike break, it does not terminate the loop entirely—it just skips the
rest of the code in the current iteration.

How it Works

1. When continue is executed inside a loop, the remaining statements in that iteration are
ignored.

2. In for loops, the increment/decrement step is executed, and then the loop condition is
checked for the next iteration.

3. In while and do-while loops, control jumps to the condition check immediately.

Syntax

continue;

Return Statement in Java

Definition
The return statement is used in a method to exit from the method and optionally return a value
to the caller.

• In void methods, it is used without any value, simply to exit the method.

• In methods with a return type, it must return a value that matches the method's
declared return type.

How it Works

1. When the return statement is encountered, the method stops executing immediately.

2. If the method has a return type, the return statement must provide a value of that type.

3. After return executes, control is passed back to the method caller.

Syntax

return; // used in void methods

return value; // used in methods with a return type


Advance Java – Module 1

4.Arrays and Strings:

4.1 Single-dimensional array:

Definition

A single-dimensional array in Java is a collection of elements of the same data type stored in
contiguous memory locations and accessed using an index.
It allows you to store multiple values under one variable name, using indices to differentiate
them.

Key Points

• The index of an array starts at 0 and goes up to length - 1.

• Arrays are objects in Java (created in heap memory).

• Size of an array is fixed and must be specified at creation.

• Supports both declaration + initialization together or separately.

• Can hold primitive types or objects.

Syntax

// Declaration

dataType[] arrayName; // Recommended

dataType arrayName[]; // Allowed but not preferred

// Memory Allocation

arrayName = new dataType[size];

// Declaration + Initialization

dataType[] arrayName = new dataType[size];

// Inline Initialization
Advance Java – Module 1

dataType[] arrayName = {value1, value2, value3, ...};

How It Works

1. When you create an array using new, memory is allocated in the heap.

2. The reference variable (e.g., arr) points to the array’s memory location.

3. The length of the array is fixed and can be accessed using .length property.

4. Accessing an element outside the valid range throws ArrayIndexOutOfBoundsException.

Example 1 – Declaration, Creation, Initialization Separately

public class ArrayExample1 {

public static void main(String[] args) {

int[] numbers; // Declaration

numbers = new int[5]; // Memory allocation

// Initialization

numbers[0] = 10;

numbers[1] = 20;

numbers[2] = 30;

numbers[3] = 40;

numbers[4] = 50;

// Accessing elements

for (int i = 0; i < numbers.length; i++) {

System.out.println("Element at index " + i + ": " + numbers[i]);

}
Advance Java – Module 1

Output:

Element at index 0: 10

Element at index 1: 20

Element at index 2: 30

Element at index 3: 40

Element at index 4: 50

Example 2 – Inline Initialization

public class ArrayExample2 {

public static void main(String[] args) {

String[] fruits = {"Apple", "Banana", "Cherry"};

for (int i = 0; i < fruits.length; i++) {

System.out.println(fruits[i]);

Output:

Apple

Banana

Cherry

Example 3 – Using Enhanced For Loop

public class ArrayExample3 {

public static void main(String[] args) {


Advance Java – Module 1

double[] prices = {10.5, 20.75, 30.0};

for (double price : prices) {

System.out.println(price);

Output:

10.5

20.75

30.0

Default Values in Arrays

When an array is created without explicit initialization, Java assigns default values:

• Numeric types → 0

• char → '\u0000' (null character)

• boolean → false

• Object references → null

Example:

public class DefaultValuesExample {

public static void main(String[] args) {

int[] numbers = new int[3];

System.out.println(numbers[0]); // 0

System.out.println(numbers[1]); // 0

System.out.println(numbers[2]); // 0

}
Advance Java – Module 1

4.2 Multi-Dimensional Arrays

Definition

A multi-dimensional array is an array of arrays. The most common type is a 2D array (matrix-
like structure).

Types

• Rectangular arrays — each row has the same number of columns.

• Jagged arrays — rows have different column sizes.

How it Works

• In Java, a 2D array is actually an array where each element is a reference to another


array.

• Memory is allocated separately for each row.

Example Memory Layout:

int[][] arr = { {1, 2}, {3, 4, 5} };

// arr[0] → [1][2] (length 2)

// arr[1] → [3][4][5] (length 3)

Syntax

datatype[][] arrayName = new datatype[rows][cols];

datatype[][] arrayName = { {val1, val2}, {val3, val4} };

Example Code

public class MultiArrayExample {

public static void main(String[] args) {

// 2D array initialization

int[][] matrix = {

{1, 2, 3},

{4, 5, 6}
Advance Java – Module 1

};

// Accessing elements

System.out.println("Element at (0,1): " + matrix[0][1]);

// Iterating through 2D array

System.out.println("Matrix elements:");

for (int i = 0; i < matrix.length; i++) {

for (int j = 0; j < matrix[i].length; j++) {

System.out.print(matrix[i][j] + " ");

System.out.println();

Output

Element at (0,1): 2

Matrix elements:

123

456

4.3 Array Operations (Copying, Sorting, Searching)

1. Copying Arrays

Definition

Copying an array means creating a new array and transferring the elements from one array to
another.
Advance Java – Module 1

Ways to Copy

1. Manual copy using a loop — element-by-element copy.

2. System.arraycopy() — efficient native method.

3. Arrays.copyOf() — returns a new array with the specified length.

4. clone() — creates a shallow copy of the array.

Syntax & Example

import java.util.Arrays;

public class ArrayCopyExample {

public static void main(String[] args) {

int[] original = {1, 2, 3, 4, 5};

// 1. Manual copy

int[] manualCopy = new int[original.length];

for (int i = 0; i < original.length; i++) {

manualCopy[i] = original[i];

// 2. System.arraycopy()

int[] sysCopy = new int[original.length];

System.arraycopy(original, 0, sysCopy, 0, original.length);

// 3. Arrays.copyOf()

int[] arraysCopy = Arrays.copyOf(original, original.length);

// 4. clone()
Advance Java – Module 1

int[] clonedCopy = original.clone();

System.out.println("Original: " + Arrays.toString(original));

System.out.println("Manual Copy: " + Arrays.toString(manualCopy));

System.out.println("System Copy: " + Arrays.toString(sysCopy));

System.out.println("Arrays.copyOf: " + Arrays.toString(arraysCopy));

System.out.println("Cloned Copy: " + Arrays.toString(clonedCopy));

Output

Original: [1, 2, 3, 4, 5]

Manual Copy: [1, 2, 3, 4, 5]

System Copy: [1, 2, 3, 4, 5]

Arrays.copyOf: [1, 2, 3, 4, 5]

Cloned Copy: [1, 2, 3, 4, 5]

2. Sorting Arrays

Definition

Sorting rearranges elements in ascending or descending order.

Ways to Sort

• Arrays.sort() — ascending order by default.

• Arrays.sort(array, Collections.reverseOrder()) — descending order for objects.

• Manual sorting algorithms — Bubble sort, Selection sort, etc. (for learning).

Syntax & Example

java
Advance Java – Module 1

import java.util.Arrays;

import java.util.Collections;

public class ArraySortExample {

public static void main(String[] args) {

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

// Ascending order

Arrays.sort(numbers);

System.out.println("Ascending: " + Arrays.toString(numbers));

// Descending order (for Integer objects)

Integer[] nums = {5, 2, 8, 1, 3};

Arrays.sort(nums, Collections.reverseOrder());

System.out.println("Descending: " + Arrays.toString(nums));

Output

Ascending: [1, 2, 3, 5, 8]

Descending: [8, 5, 3, 2, 1]

3. Searching in Arrays

Definition

Searching finds the index of an element in an array.

Types

• Linear Search — check each element (works for unsorted arrays).


Advance Java – Module 1

• Binary Search — divide-and-search (works only for sorted arrays).

Syntax & Example

import java.util.Arrays;

public class ArraySearchExample {

public static void main(String[] args) {

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

// 1. Linear Search

int target = 5;

int index = -1;

for (int i = 0; i < numbers.length; i++) {

if (numbers[i] == target) {

index = i;

break;

System.out.println("Linear Search - 5 found at index: " + index);

// 2. Binary Search (array must be sorted)

int binaryIndex = Arrays.binarySearch(numbers, 5);

System.out.println("Binary Search - 5 found at index: " + binaryIndex);

Output

Linear Search - 5 found at index: 3


Advance Java – Module 1

Binary Search - 5 found at index: 3

4.4 String Class and Methods

Definition

• In Java, a String is an object that represents a sequence of characters.

• The String class is part of the java.lang package and is immutable, meaning once a String
object is created, its value cannot be changed.

Types of String Creation

1. Using String literals

o Stored in the String Constant Pool (SCP) in the method area of memory.

o If a string with the same value exists, it will reuse the reference (no duplicate
object is created).

String s1 = "Hello";

String s2 = "Hello"; // points to the same object in SCP

2. Using new keyword

o Forces creation of a new String object in the heap, even if the value already exists
in SCP.

String s3 = new String("Hello"); // new object in heap + "Hello" in SCP

How Strings Work (Internally)

• Immutability:

o If you modify a string, a new object is created.

o The original string remains unchanged.

• Memory Model:

o SCP stores one copy of each literal string.

o Heap stores objects created via new.


Advance Java – Module 1

Example Memory Diagram:

String a = "Java";

String b = "Java"; // Points to same SCP object

String c = new String("Java"); // New heap object

Common Constructors

String(); // Empty string

String(String original); // Copy constructor

String(char[] chars); // From char array

String(char[] chars, int start, int length); // Partial array

String(byte[] byteArray); // From byte array

Common Methods of String Class

Here’s a table of frequently used methods:

Method Description Example

length() Returns string length "Hello".length() → 5

charAt(index) Returns char at position "Java".charAt(1) → 'a'

substring(start) From start index to end "Java".substring(2) → "va"

substring(start, end) From start to end-1 "Java".substring(1,3) → "av"

contains(str) Checks substring "Java".contains("va") → true

equals(str) Compares case-sensitive "Java".equals("java") → false

equalsIgnoreCase(str) Case-insensitive compare "Java".equalsIgnoreCase("java") →


true

toLowerCase() Lowercase string "JAVA".toLowerCase() → "java"

toUpperCase() Uppercase string "java".toUpperCase() → "JAVA"


Advance Java – Module 1

trim() Removes leading/trailing " hi ".trim() → "hi"


spaces

replace(old, new) Replaces chars "Java".replace('a', 'o') → "Jovo"

split(regex) Splits into array "a,b,c".split(",") → ["a","b","c"]

Example Code: Demonstrating Methods

public class StringMethodsExample {

public static void main(String[] args) {

String str = " Java Programming ";

// Basic info

System.out.println("Original: '" + str + "'");

System.out.println("Length: " + str.length());

// trim

String trimmed = str.trim();

System.out.println("Trimmed: '" + trimmed + "'");

// case change

System.out.println("Uppercase: " + trimmed.toUpperCase());

System.out.println("Lowercase: " + trimmed.toLowerCase());

// substring

System.out.println("Substring (5): " + trimmed.substring(5));

System.out.println("Substring (0,4): " + trimmed.substring(0, 4));


Advance Java – Module 1

// replace

System.out.println("Replace 'a' with '@': " + trimmed.replace('a', '@'));

// contains & equals

System.out.println("Contains 'Java': " + trimmed.contains("Java"));

System.out.println("Equals 'java programming' (ignore case): " +

trimmed.equalsIgnoreCase("java programming"));

// split

String csv = "apple,banana,grapes";

String[] fruits = csv.split(",");

System.out.print("Fruits: ");

for (String fruit : fruits) {

System.out.print(fruit + " ");

// charAt

System.out.println("\nChar at index 2: " + trimmed.charAt(2));

Output

Original: ' Java Programming '

Length: 21

Trimmed: 'Java Programming'

Uppercase: JAVA PROGRAMMING


Advance Java – Module 1

Lowercase: java programming

Substring (5): Programming

Substring (0,4): Java

Replace 'a' with '@': J@v@ Progr@mming

Contains 'Java': true

Equals 'java programming' (ignore case): true

Fruits: apple banana grapes

Char at index 2: v

Key Points to Remember

1. String is immutable → Every modification creates a new object.

2. Use StringBuilder or StringBuffer for mutable strings (we’ll cover in 4.5).

3. Always compare strings using equals() instead of == (which compares references).

4. String literals go to the String Constant Pool, objects created with new go to the heap.

4.5 StringBuffer & StringBuilder

Definition

• StringBuffer and StringBuilder are mutable sequence of characters.

• Unlike String, you can modify their contents without creating a new object.

• They are part of java.lang package.

Key Difference Between String, StringBuffer, StringBuilder

Feature String StringBuffer StringBuilder

Mutability Immutable Mutable Mutable

Thread-safe No Yes (synchronized) No


Advance Java – Module 1

Performance Slower for concat Slower (due to synchronization) Faster

Introduced in Java 1.0 Java 1.0 Java 5

How it Works

• StringBuffer: All methods are synchronized, meaning thread-safe but slower.

• StringBuilder: Methods are not synchronized, making it faster but not thread-safe.

• Both classes store characters in a char[] array internally and resize it automatically when
needed.

Constructors

java

StringBuffer(); // Default capacity 16

StringBuffer(String str); // Initialize with a string

StringBuffer(int capacity); // Initialize with given capacity

StringBuilder();

StringBuilder(String str);

StringBuilder(int capacity);

Common Methods (Both Classes)

Method Description Example

append(str) Adds text at the end sb.append("Java")

insert(offset, str) Inserts text at position sb.insert(1, "Hi")

replace(start, end, str) Replaces substring sb.replace(0, 4, "Hi")

delete(start, end) Deletes characters sb.delete(0, 3)


Advance Java – Module 1

reverse() Reverses the sequence sb.reverse()

capacity() Current storage capacity sb.capacity()

length() Current length of content sb.length()

charAt(index) Returns character at position sb.charAt(2)

Example: StringBuffer

public class StringBufferExample {

public static void main(String[] args) {

StringBuffer sb = new StringBuffer("Hello");

sb.append(" World");

System.out.println("After append: " + sb);

sb.insert(6, "Java ");

System.out.println("After insert: " + sb);

sb.replace(6, 10, "C++");

System.out.println("After replace: " + sb);

sb.delete(6, 10);

System.out.println("After delete: " + sb);

sb.reverse();

System.out.println("After reverse: " + sb);

System.out.println("Capacity: " + sb.capacity());


Advance Java – Module 1

System.out.println("Length: " + sb.length());

Output

After append: Hello World

After insert: Hello Java World

After replace: Hello C++ World

After delete: Hello World

After reverse: dlroW olleH

Capacity: 21

Length: 11

Example: StringBuilder

public class StringBuilderExample {

public static void main(String[] args) {

StringBuilder sb = new StringBuilder("Data");

sb.append(" Science");

System.out.println("After append: " + sb);

sb.insert(5, "Java ");

System.out.println("After insert: " + sb);

sb.replace(5, 9, "Python");

System.out.println("After replace: " + sb);


Advance Java – Module 1

sb.delete(5, 11);

System.out.println("After delete: " + sb);

sb.reverse();

System.out.println("After reverse: " + sb);

Output

After append: Data Science

After insert: Data Java Science

After replace: Data Python Science

After delete: Data Science

After reverse: ecneicS ataD

Performance Tip

• Use StringBuilder when thread safety is not required (single-threaded).

• Use StringBuffer when multiple threads will modify the same string object.

4.6 String Immutability & Interning

1. String Immutability

Definition

A String in Java is immutable, meaning once a String object is created, its value cannot be
changed.
Any modification (concatenation, replace, substring, etc.) creates a new String object instead of
changing the existing one.

Why String is Immutable?


Advance Java – Module 1

1. Security: Strings are used for sensitive data (e.g., database URLs, file paths, usernames,
passwords). If they were mutable, malicious code could change values without
detection.

2. Caching & Performance: Strings are stored in the String Constant Pool (SCP).
Immutability ensures one literal is reused without worrying about it being altered.

3. Thread Safety: Multiple threads can share a String without synchronization.

4. Hashcode Consistency: Strings are used as keys in hash-based collections (HashMap,


HashSet). If a String were mutable, its hashcode could change, breaking map lookups.

Example of Immutability

public class StringImmutability {

public static void main(String[] args) {

String s1 = "Java";

String s2 = s1.concat(" Programming");

System.out.println("s1: " + s1); // Original unchanged

System.out.println("s2: " + s2); // New object created

Output

s1: Java

s2: Java Programming

Here, s1.concat(...) didn’t change s1. A new String object was created for s2.

2. String Interning

Definition
Advance Java – Module 1

Interning means storing only one copy of each distinct String literal in the SCP (String Constant
Pool) so that all variables with the same value share the same reference.

How it Works

• When you create a String literal, JVM checks the SCP:

o If it exists → returns the existing reference.

o If it doesn’t exist → creates a new object in SCP.

• When you use new String("text"):

o Creates a new object in heap.

o Also places "text" in SCP (if not already there).

Using intern() Method

• The intern() method ensures a String is added to the SCP and returns the reference from
the SCP.

String s1 = new String("Hello");

String s2 = "Hello";

System.out.println(s1 == s2); // false (different memory)

System.out.println(s1.intern() == s2); // true (same SCP reference)

Example: Interning & Memory Behavior

public class StringInternExample {

public static void main(String[] args) {

String a = "Java"; // stored in SCP

String b = "Java"; // reuses SCP reference

String c = new String("Java"); // new object in heap

String d = c.intern(); // gets SCP reference


Advance Java – Module 1

System.out.println(a == b); // true

System.out.println(a == c); // false

System.out.println(a == d); // true

Output

true

false

true

Memory Diagram

SCP:

"Java" ← a, b, d reference here

Heap:

[Java] (c references this)

Key Takeaways

1. Immutable → safer, faster for constants, and thread-safe.

2. SCP → avoids duplicate String literals in memory.

3. Use intern() to explicitly add strings to SCP.

4. Use StringBuilder/StringBuffer for mutable strings.

4.7 Common String Operations

This section is basically a toolbox of daily String tasks you’ll perform in Java.
We’ll go through each operation with definition → usage → syntax → code → output.
Advance Java – Module 1

1. Concatenation

Definition: Joining two or more strings together.


Ways:

• Using + operator.

• Using concat() method.

• Using StringBuilder/StringBuffer for better performance in loops.

public class ConcatenationExample {

public static void main(String[] args) {

String s1 = "Java";

String s2 = "Programming";

String result1 = s1 + " " + s2;

String result2 = s1.concat(" ").concat(s2);

System.out.println("Using +: " + result1);

System.out.println("Using concat(): " + result2);

Output:

Using +: Java Programming

Using concat(): Java Programming

2. Comparison

Definition: Checking if two strings are equal or ordering them lexicographically.

• equals() → case-sensitive equality.


Advance Java – Module 1

• equalsIgnoreCase() → case-insensitive equality.

• compareTo() → returns 0 if equal, >0 if first > second, <0 if first < second.

public class ComparisonExample {

public static void main(String[] args) {

String a = "Java";

String b = "java";

System.out.println(a.equals(b)); // false

System.out.println(a.equalsIgnoreCase(b)); // true

System.out.println(a.compareTo("Java")); // 0

System.out.println(a.compareTo("Python")); // negative (Java < Python)

3. Substring Extraction

Definition: Extracting part of a string using substring(start) or substring(start, end).

public class SubstringExample {

public static void main(String[] args) {

String text = "Java Programming";

System.out.println(text.substring(5)); // Programming

System.out.println(text.substring(0, 4)); // Java

4. Splitting Strings
Advance Java – Module 1

Definition: Breaking a string into parts using a delimiter with split().

public class SplitExample {

public static void main(String[] args) {

String csv = "apple,banana,grapes";

String[] fruits = csv.split(",");

for (String fruit : fruits) {

System.out.println(fruit);

Output:

apple

banana

grapes

5. Joining Strings

Definition: Opposite of split — combining multiple strings into one with a delimiter.

import java.util.StringJoiner;

import java.util.Arrays;

public class JoinExample {

public static void main(String[] args) {

StringJoiner sj = new StringJoiner(", ");

sj.add("apple").add("banana").add("grapes");

System.out.println(sj); // apple, banana, grapes


Advance Java – Module 1

// Using String.join()

String joined = String.join(" - ", Arrays.asList("A", "B", "C"));

System.out.println(joined); // A - B - C

6. Trimming Spaces

Definition: Removing leading and trailing spaces using trim() or strip() (Java 11+).

public class TrimExample {

public static void main(String[] args) {

String name = " Java ";

System.out.println("Trimmed: '" + name.trim() + "'");

Output:

Trimmed: 'Java'

7. Changing Case

Definition: Converting all characters to uppercase or lowercase.

public class CaseExample {

public static void main(String[] args) {

String str = "Java";

System.out.println(str.toUpperCase()); // JAVA

System.out.println(str.toLowerCase()); // java

}
Advance Java – Module 1

8. Replacing Characters or Substrings

public class ReplaceExample {

public static void main(String[] args) {

String text = "I like Java";

System.out.println(text.replace("Java", "Python"));

System.out.println(text.replace('a', '@'));

Output:

I like Python

I like J@v@

9. Checking Prefixes & Suffixes

public class PrefixSuffixExample {

public static void main(String[] args) {

String filename = "report.pdf";

System.out.println(filename.startsWith("report")); // true

System.out.println(filename.endsWith(".pdf")); // true

10. Searching in Strings


Advance Java – Module 1

public class SearchExample {

public static void main(String[] args) {

String sentence = "Java is fun";

System.out.println(sentence.indexOf("is")); // 5

System.out.println(sentence.contains("fun")); // true

5. Methods in Java

A method in Java is a block of code that performs a specific task, can be reused, and is executed
when called.
They help in modularity (breaking down code into smaller parts) and code reusability.

5.1 Understanding Methods in Java

Definition

A method is a collection of statements grouped together to perform an operation.


A method can:

• Take input (parameters)

• Perform an operation

• Return a result (or not, if void)

5.1.1 Syntax of a Method

modifier returnType methodName(parameterList) {

// method body

// statements

return value; // if returnType is not void


Advance Java – Module 1

Explanation of parts:

1. modifier – Defines access level (public, private, protected, or default).

2. returnType – Data type of the value returned (int, String, void, etc.).

3. methodName – Unique name for identifying the method.

4. parameterList – Zero or more parameters inside parentheses.

5. method body – The code block {} where the operation happens.

5.1.2 Types of Methods

(a) Predefined (Built-in) Methods

Already available in Java libraries.


Examples:

Math.sqrt(16); // returns 4.0

System.out.println("Hello");

(b) User-defined Methods

Created by the programmer to perform a specific task.

Example:

public class Calculator {

public int add(int a, int b) { // user-defined method

return a + b;

public static void main(String[] args) {

Calculator calc = new Calculator();

int sum = calc.add(5, 3);

System.out.println("Sum: " + sum);


Advance Java – Module 1

5.1.3 Method Declaration vs Method Call

Declaration – Defining how the method works.


Call – Requesting the method to execute.

Example:

// Declaration

void greet() {

System.out.println("Hello, welcome!");

// Call

greet();

5.1.4 Returning a Value

Methods can return results using the return keyword.

Example:

public int square(int num) {

return num * num;

5.1.5 Method Parameters

• Pass by Value – Java passes a copy of the value to the method.

• Multiple Parameters – Separate with commas.

Example:
Advance Java – Module 1

void displayInfo(String name, int age) {

System.out.println(name + " is " + age + " years old.");

5.1.6 Static vs Non-static Methods

Static Methods:

• Belong to the class, not objects.

• Called using the class name.

class Test {

static void sayHello() {

System.out.println("Hello from static method");

public static void main(String[] args) {

Test.sayHello();

Non-static Methods:

• Belong to object instances.

• Require an object to call.

5.1.7 Method Overloading

Defining multiple methods with the same name but different parameter lists.

Example:

class MathOps {

int sum(int a, int b) { return a + b; }


Advance Java – Module 1

double sum(double a, double b) { return a + b; }

5.1.8 Example – Complete Program

public class MethodDemo {

// 1. User-defined method with parameters and return value

public int multiply(int x, int y) {

return x * y;

// 2. Void method

public void greet(String name) {

System.out.println("Hello, " + name + "!");

// 3. Static method

public static void displayInfo() {

System.out.println("Static method example");

public static void main(String[] args) {

MethodDemo obj = new MethodDemo();

// calling non-static methods

int result = obj.multiply(4, 5);


Advance Java – Module 1

System.out.println("Multiplication: " + result);

obj.greet("Chan");

// calling static method

MethodDemo.displayInfo();

Key Points to Remember

• Methods increase reusability and make code cleaner.

• Java always passes parameters by value.

• Static methods belong to the class; non-static methods belong to objects.

• Overloading allows flexibility in method calls.

5.2 Parameter Passing in Java (By Value vs. By Reference)

1. How Parameter Passing Works in Java

In Java, all arguments are passed by value, but the “value” can be:

• Primitive value → The actual value (e.g., 5, true, 'A')

• Object reference → The memory address (reference) to the object

However, Java never passes parameters by reference like C++ (where you can directly modify
the caller’s variable).

2. Passing Primitives (By Value)

When a primitive is passed to a method:

• A copy of the value is made.


Advance Java – Module 1

• Changes inside the method do not affect the original variable.

Example:

public class PassByValueDemo {

public static void main(String[] args) {

int num = 10;

changeValue(num);

System.out.println("After method call: " + num); // Output: 10

static void changeValue(int x) {

x = 20; // Only changes local copy

3. Passing Objects (Reference is Passed by Value)

When an object is passed:

• A copy of the reference is passed.

• Both the original and the method parameter point to the same object.

• Changes to the object’s fields will reflect outside the method.

• Reassigning the reference inside the method does not affect the original reference.

Example 1 – Modifying Object Fields (Affects Original):

class Person {

String name;

public class PassByReferenceDemo {


Advance Java – Module 1

public static void main(String[] args) {

Person p = new Person();

p.name = "Alice";

changeName(p);

System.out.println("After method call: " + p.name); // Output: Bob

static void changeName(Person person) {

person.name = "Bob"; // Changes original object

Example 2 – Reassigning Reference (Does NOT Affect Original):

public class ReassignReferenceDemo {

public static void main(String[] args) {

Person p = new Person();

p.name = "Alice";

reassignPerson(p);

System.out.println("After method call: " + p.name); // Output: Alice

static void reassignPerson(Person person) {

person = new Person(); // New object created

person.name = "Bob"; // Only affects new object

}
Advance Java – Module 1

4. Key Points to Remember

1. Java is always pass-by-value.

2. For primitives → copy of value is passed → no effect outside.

3. For objects → copy of reference is passed → changes to object’s fields affect the original.

4. Reassigning the reference inside the method does not affect the caller’s variable.

5.3 Method Overloading

Definition

Method Overloading in Java is the ability to define multiple methods in the same class with the
same method name but different parameter lists (different number of parameters or different
types of parameters).
It is a type of compile-time polymorphism (also known as static polymorphism).

Key Rules for Method Overloading

1. Same Method Name


All overloaded methods must have the same name.

2. Different Parameter List


At least one of the following must be different:

o Number of parameters

o Data types of parameters

o Order of parameters

3. Return Type Can Be Same or Different


But return type alone cannot differentiate methods — the parameter list must differ.

4. Access Modifier & Exceptions


These can differ but do not affect overloading.

5. Compile-Time Binding
The method to be called is determined at compile time based on the arguments passed.
Advance Java – Module 1

Example: Method Overloading

class MathUtils {

// Overloaded method with 2 int parameters

int add(int a, int b) {

return a + b;

// Overloaded method with 3 int parameters

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

return a + b + c;

// Overloaded method with 2 double parameters

double add(double a, double b) {

return a + b;

// Overloaded method with different parameter order

String add(String a, int b) {

return a + b;

public class Main {

public static void main(String[] args) {


Advance Java – Module 1

MathUtils obj = new MathUtils();

System.out.println(obj.add(10, 20)); // calls int, int

System.out.println(obj.add(10, 20, 30)); // calls int, int, int

System.out.println(obj.add(5.5, 6.5)); // calls double, double

System.out.println(obj.add("Hello", 5)); // calls String, int

Output

30

60

12.0

Hello5

Common Mistakes

Only changing return type will not work:

java

int sum(int a, int b) { return a + b; }

double sum(int a, int b) { return a + b; } // Compilation error

Overloading with same parameter type & count but different variable names is not valid.

Real-World Example

• println() method in Java is overloaded:

System.out.println(10); // int
Advance Java – Module 1

System.out.println(10.5); // double

System.out.println("Hello"); // String

System.out.println(true); // boolean

The JVM decides at compile time which version to call based on the argument type.

5.4 Recursion in Java

Definition

Recursion is a programming technique where a method calls itself to solve a smaller instance of
the same problem until a base condition is met.
It’s a way to solve problems by breaking them down into simpler sub-problems of the same
type.

How Recursion Works

• A recursive method calls itself with a modified parameter.

• There must be a base case (termination condition) to stop the recursive calls; otherwise,
it causes infinite recursion and a StackOverflowError.

• Each recursive call adds a new frame to the call stack until base case is reached, then the
calls return in reverse order.

Syntax of a Recursive Method

returnType methodName(parameters) {

if (base condition) {

// base case: stop recursion

return someValue;

} else {

// recursive call

return methodName(modifiedParameters);
Advance Java – Module 1

Example 1: Factorial Calculation

Factorial of n (written as n!) is:

• n! = n * (n-1) * (n-2) * ... * 1

• By definition, 0! = 1.

Recursive formula:

factorial(n) = n * factorial(n-1), where factorial(0) = 1

public class RecursionExample {

public static int factorial(int n) {

if (n == 0) { // base case

return 1;

} else {

return n * factorial(n - 1); // recursive call

public static void main(String[] args) {

int number = 5;

int fact = factorial(number);

System.out.println("Factorial of " + number + " is: " + fact);

Output:
Advance Java – Module 1

Factorial of 5 is: 120

Example 2: Fibonacci Series

Fibonacci sequence:

• Each number is the sum of the two preceding ones.

• fib(0) = 0, fib(1) = 1

Recursive formula:

fib(n) = fib(n-1) + fib(n-2)

public class FibonacciExample {

public static int fib(int n) {

if (n == 0) return 0; // base cases

if (n == 1) return 1;

return fib(n - 1) + fib(n - 2); // recursive call

public static void main(String[] args) {

int count = 7;

System.out.print("Fibonacci series up to " + count + ": ");

for (int i = 0; i < count; i++) {

System.out.print(fib(i) + " ");

Output:
Advance Java – Module 1

Fibonacci series up to 7: 0 1 1 2 3 5 8

Key Points

• Always define a base case to stop recursion.

• Recursive calls use stack memory — too deep recursion causes StackOverflowError.

• Recursion can be replaced by iteration but is more intuitive for problems like tree
traversal, factorial, Fibonacci, etc.

Visual: Recursive Calls for factorial(3)

factorial(3)

= 3 * factorial(2)

= 3 * (2 * factorial(1))

= 3 * (2 * (1 * factorial(0)))

= 3 * (2 * (1 * 1)) = 6

5.5 Varargs (Variable Arguments) in Java

Definition

Varargs allow a method to accept zero or more arguments of the same type as parameters.
Introduced in Java 5, it provides flexibility so you don’t have to overload methods for different
numbers of parameters.

How Varargs Work

• Syntax uses three dots ... after the data type.

• Inside the method, the varargs parameter is treated as an array.

• You can only have one varargs parameter per method and it must be the last
parameter.
Advance Java – Module 1

Syntax

returnType methodName(dataType... varName) {

// method body, varName is treated like an array

Example:

void printNumbers(int... numbers) {

for (int num : numbers) {

System.out.print(num + " ");

Examples

Example 1: Simple Varargs Method

public class VarargsExample {

static void printNumbers(int... numbers) {

System.out.print("Numbers: ");

for (int num : numbers) {

System.out.print(num + " ");

System.out.println();

public static void main(String[] args) {

printNumbers(1, 2, 3);

printNumbers(10, 20);

printNumbers(); // zero arguments allowed


Advance Java – Module 1

Output:

Numbers: 1 2 3

Numbers: 10 20

Numbers:

Example 2: Varargs with Other Parameters

public class VarargsWithOtherParams {

static void display(String name, int... scores) {

System.out.print(name + "'s scores: ");

for (int score : scores) {

System.out.print(score + " ");

System.out.println();

public static void main(String[] args) {

display("Alice", 90, 80, 85);

display("Bob");

Output:

Alice's scores: 90 80 85

Bob's scores:
Advance Java – Module 1

Important Notes

• You cannot have more than one varargs parameter in a method.

• The varargs parameter must be the last parameter in the parameter list.

• Varargs is internally treated as an array.

• Using varargs helps avoid multiple overloaded methods with varying parameter counts.

Example with Array and Varargs

Both these method calls are valid and equivalent:

printNumbers(new int[]{1, 2, 3});

printNumbers(1, 2, 3);

Comparison with Overloading

Without varargs, you might write multiple overloaded methods like:

void printNumbers(int a) { ... }

void printNumbers(int a, int b) { ... }

void printNumbers(int a, int b, int c) { ... }

With varargs, one method covers all.

5.6 main() Method Deep Dive

What is the main() Method?

• The main() method is the entry point of any Java application.

• When you run a Java program, the JVM looks for the main() method to start execution.

• It is where the program begins and ends.

Standard Syntax

public static void main(String[] args)


Advance Java – Module 1

Breaking Down the Syntax

Part Meaning

public Access modifier — must be public so JVM can access it from outside the class.

static JVM calls this method without creating an object of the class. Static means the
method belongs to the class itself.

void Return type — main() does not return any value.

main Method name — must be exactly main.

String[] Parameter — an array of strings which stores command-line arguments passed


args to the program.

Why These Keywords Are Mandatory?

• public — JVM needs to call it from outside the class.

• static — JVM calls main() without creating an instance of the class.

• void — JVM doesn’t expect any return value after execution.

• String[] args — Accepts arguments from the command line, which makes your program
flexible.

Command-Line Arguments

You can pass arguments to a Java program via the command line like this:

java MyProgram Hello World 123

Inside the program:

public class MyProgram {

public static void main(String[] args) {

for (String arg : args) {

System.out.println(arg);

}
Advance Java – Module 1

Output:

Hello

World

123

Common Variations of main()

Technically, these are valid but not recommended or not used by JVM as entry point:

Variation Explanation

public static void main(String... args) Uses varargs instead of array (valid).

public static void main(String args[]) Array declaration syntax variation (valid).

static public void main(String[] args) Order of modifiers doesn’t matter (valid).

public void main(String[] args) Non-static — JVM cannot call this directly.

public static int main(String[] args) Return type not void — JVM won’t use it as entry.

private static void main(String[] args) Not public — JVM cannot access.

Example: Command-Line Arguments

public class CommandLineDemo {

public static void main(String[] args) {

if (args.length == 0) {

System.out.println("No arguments passed");

} else {

System.out.println("Arguments passed:");

for (String arg : args) {

System.out.println(arg);
Advance Java – Module 1

Run with:

java CommandLineDemo Java 2025

Output:

Arguments passed:

Java

2025

Why Is main() Static?

• The JVM doesn’t instantiate your class to call main().

• It directly calls main() via the class name.

• Being static allows calling it without creating an object.

Can main() Be Overloaded?

Yes, you can overload main() by creating multiple methods with the same name but different
parameters.

public class MainOverload {

public static void main(String[] args) {

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

main(10); // calling overloaded method

public static void main(int num) {


Advance Java – Module 1

System.out.println("Overloaded main: " + num);

Output:

Main with String[]

Overloaded main: 10

But JVM always calls the main(String[] args) method as the program’s entry point.

Summary

Point Description

Purpose Entry point for Java programs

Signature public static void main(String[] args)

Static So JVM can call it without object instantiation

Command-line args String array to receive program arguments

Can be overloaded Yes, but JVM calls only the exact signature

6. Object-Oriented Programming (OOP)

6.1 Classes and Objects

Definition

• Class:
A class is a blueprint or template for creating objects. It defines properties (fields) and
behaviors (methods) that the objects created from the class will have.
Think of a class as a blueprint of a house — it defines the design but isn’t the actual
house.

• Object:
An object is an instance of a class. It represents an actual entity with state and behavior
defined by the class.
Continuing the analogy, the object is an actual house built using the blueprint.
Advance Java – Module 1

How Classes and Objects Work

• A class groups related variables (fields) and methods (functions) together.

• You can create multiple objects from a class.

• Each object has its own copy of fields and can call methods.

Syntax

java

// Class declaration

class ClassName {

// Fields (variables)

dataType field1;

dataType field2;

// Methods (functions)

returnType methodName(parameters) {

// method body

Creating Objects

java

ClassName obj = new ClassName();

• new keyword allocates memory and returns the reference to the object.

• obj is a reference variable that points to the object.


Advance Java – Module 1

Example

java

class Car {

// Fields (attributes)

String color;

String model;

int year;

// Method (behavior)

void displayInfo() {

System.out.println("Car Model: " + model);

System.out.println("Color: " + color);

System.out.println("Year: " + year);

public class TestCar {

public static void main(String[] args) {

// Create an object of Car

Car car1 = new Car();

// Set fields

car1.color = "Red";

car1.model = "Tesla Model S";


Advance Java – Module 1

car1.year = 2023;

// Call method

car1.displayInfo();

Output

Car Model: Tesla Model S

Color: Red

Year: 2023

Important Concepts

• Reference Variable: Points to the object stored in heap memory.

• Heap Memory: Where actual objects are stored.

• Multiple Objects: You can create many objects with different states.

Car car2 = new Car();

car2.color = "Blue";

car2.model = "BMW X5";

car2.year = 2022;

• car1 and car2 are two different objects with independent data.

Summary
Advance Java – Module 1

Term Description

Class Blueprint for objects; defines variables & methods.

Object Instance of a class; actual entity with state and behavior.

Fields Variables inside class to hold data.

Methods Functions inside class to define behaviors.

new Keyword to create an object and allocate memory.

6.2 Constructors & Constructor Overloading

What is a Constructor?

• A constructor is a special method in a class that is called automatically when an object


is created.

• Its purpose is to initialize the new object.

• A constructor has the same name as the class and no return type (not even void).

Key Characteristics

Property Description

Name Must be the same as the class name

Return Type None (not even void)

Invocation Automatically called with new

Purpose Initialize object’s fields

Can be overloaded Yes, multiple constructors with different parameters

Default Constructor

• If you do not define any constructor, the Java compiler provides a default constructor
(no-arg constructor) automatically.
Advance Java – Module 1

• The default constructor initializes instance variables with default values (0, null, false,
etc.).

Example:

class Person {

String name;

int age;

public class TestPerson {

public static void main(String[] args) {

Person p = new Person(); // default constructor is called

System.out.println(p.name); // null

System.out.println(p.age); // 0

Parameterized Constructor

• You can define your own constructor that takes parameters to initialize the object with
specific values.

Syntax:

class ClassName {

ClassName(parameters) {

// initialization code

Example:

class Person {
Advance Java – Module 1

String name;

int age;

// Parameterized constructor

Person(String name, int age) {

this.name = name;

this.age = age;

public class TestPerson {

public static void main(String[] args) {

Person p = new Person("Alice", 30); // parameterized constructor called

System.out.println(p.name); // Alice

System.out.println(p.age); // 30

Constructor Overloading

• You can have multiple constructors in the same class with different parameter lists.

• The compiler decides which constructor to call based on the arguments passed.

Example:

class Person {

String name;

int age;
Advance Java – Module 1

// No-arg constructor

Person() {

name = "Unknown";

age = 0;

// Parameterized constructor

Person(String name) {

this.name = name;

age = 0;

// Parameterized constructor with two parameters

Person(String name, int age) {

this.name = name;

this.age = age;

public class TestPerson {

public static void main(String[] args) {

Person p1 = new Person();

Person p2 = new Person("Bob");

Person p3 = new Person("Charlie", 25);

System.out.println(p1.name + ", " + p1.age); // Unknown, 0


Advance Java – Module 1

System.out.println(p2.name + ", " + p2.age); // Bob, 0

System.out.println(p3.name + ", " + p3.age); // Charlie, 25

Important Points

• Constructors do not have return types.

• If you define any constructor, the default no-arg constructor is not provided
automatically.

• Use this keyword inside constructor to refer to the current object’s fields (explained in
6.3).

• Constructors can call other constructors using constructor chaining (this(...)) —


explained later.

Summary

Term Description

Constructor Special method to initialize new objects.

Default constructor No-arg constructor auto-provided if none defined.

Parameterized constructor Constructor with parameters to initialize fields.

Constructor Overloading Multiple constructors with different parameters.

6.3 this Keyword

Definition

• this is a reference variable in Java that refers to the current object — the instance on
which a method or constructor is being called.
Advance Java – Module 1

• It helps distinguish between instance variables and local variables when they have the
same name.

• It is also used to call other constructors in the same class (constructor chaining).

Uses of this Keyword

Use Case Explanation Example

Refer to current object’s Disambiguate between local and this.name = name; inside a
instance variable instance variables constructor

Call another constructor To reuse constructor code and this(10, 20); inside a
in the same class avoid duplication (this(...)) constructor

Pass current object as Pass current object reference to someMethod(this);


argument another method or constructor

Return current object To allow method chaining return this;


from method

1. Using this to Refer to Instance Variables

When a constructor or method has a parameter with the same name as an instance variable,
this clarifies which is which.

Example:

class Person {

String name;

int age;

Person(String name, int age) {

this.name = name; // 'this.name' refers to instance variable, 'name' refers to parameter

this.age = age;

}
Advance Java – Module 1

void display() {

System.out.println("Name: " + this.name);

System.out.println("Age: " + this.age);

public class TestThis {

public static void main(String[] args) {

Person p = new Person("Alice", 25);

p.display();

Output:

Name: Alice

Age: 25

2. Using this() to Call Another Constructor (Constructor Chaining)

this() calls another constructor in the same class. It must be the first statement in the
constructor.

Example:

class Person {

String name;

int age;

Person() {
Advance Java – Module 1

this("Unknown", 0); // calls parameterized constructor

Person(String name, int age) {

this.name = name;

this.age = age;

void display() {

System.out.println(name + " - " + age);

public class TestThisConstructor {

public static void main(String[] args) {

Person p1 = new Person();

Person p2 = new Person("Bob", 30);

p1.display(); // Unknown - 0

p2.display(); // Bob - 30

3. Passing Current Object Using this

You can pass the current object to another method or constructor.


Advance Java – Module 1

class Printer {

void print(Person p) {

System.out.println(p.name + ", " + p.age);

class Person {

String name;

int age;

Person(String name, int age) {

this.name = name;

this.age = age;

void show() {

Printer printer = new Printer();

printer.print(this); // passing current object

public class TestThisPass {

public static void main(String[] args) {

Person p = new Person("Alice", 25);

p.show();

}
Advance Java – Module 1

Output:

Alice, 25

4. Returning Current Object (Method Chaining)

class Person {

String name;

int age;

Person setName(String name) {

this.name = name;

return this;

Person setAge(int age) {

this.age = age;

return this;

void display() {

System.out.println(name + ", " + age);

}
Advance Java – Module 1

public class TestThisChain {

public static void main(String[] args) {

Person p = new Person();

p.setName("Bob").setAge(30);

p.display();

Output:

Bob, 30

Important Notes

• this cannot be used in static contexts because static methods belong to the class, not to
any object.

• Use this mainly to resolve naming conflicts and for constructor chaining.

• this increases code clarity and helps avoid bugs.

6.4 static Keyword in Java

Definition

• The static keyword in Java means "belongs to the class rather than instances (objects)".

• When you declare a variable, method, or block as static, it belongs to the class itself and
not to any specific object.

• All instances of the class share the same static members.

Where can static be used?

Usage Description
Advance Java – Module 1

Static Variables Also called class variables; shared across all instances.

Static Methods Methods that can be called without creating an object.

Static Blocks Used to initialize static variables. Executes once when the class is
loaded.

Static Nested Nested classes declared static (more in topic 6.12).


Classes

1. Static Variables

• Declared using static keyword inside a class but outside methods.

• Only one copy exists, shared by all objects of the class.

• Used for constants or counters that are common to all instances.

Example:

class Counter {

static int count = 0; // static variable

Counter() {

count++; // Increment when new object is created

static void displayCount() {

System.out.println("Count: " + count);

public class TestStaticVar {

public static void main(String[] args) {


Advance Java – Module 1

Counter c1 = new Counter();

Counter c2 = new Counter();

Counter c3 = new Counter();

Counter.displayCount(); // Output: Count: 3

Output:

Count: 3

2. Static Methods

• Declared with static keyword.

• Can be called without creating an object.

• Cannot access instance variables or methods directly because they belong to objects.

• Can access static variables and other static methods directly.

• Can only use this keyword in instance methods, so this is not available in static
methods.

Example:

class MathUtils {

static int square(int x) {

return x * x;

public class TestStaticMethod {


Advance Java – Module 1

public static void main(String[] args) {

int result = MathUtils.square(5); // call without object

System.out.println("Square of 5 is: " + result);

Output:

Square of 5 is: 25

3. Static Blocks

• A static initialization block is used to initialize static variables.

• It runs once when the class is loaded (before any object is created).

• Useful for complex initialization.

Example:

class Demo {

static int data;

static {

data = 100;

System.out.println("Static block executed");

static void display() {

System.out.println("Data: " + data);

}
Advance Java – Module 1

public class TestStaticBlock {

public static void main(String[] args) {

Demo.display();

Output:

Static block executed

Data: 100

Summary Table

Static Member Description

Static Variable Single copy shared by all instances of the class

Static Method Can be called without an object; no access to instance members

Static Block Executes once when class is loaded; used for static init

Important Notes

• Static members belong to the class, not individual objects.

• Access static members using the class name, e.g., ClassName.staticMethod().

• Instance methods can access static variables and methods directly.

• Static methods cannot access instance variables or methods directly.

• main() method is static so JVM can call it without creating an object.

6.5 Encapsulation & Access Modifiers


Advance Java – Module 1

What is Encapsulation?

• Encapsulation is one of the fundamental concepts of Object-Oriented Programming


(OOP).

• It means wrapping data (variables) and code (methods) together as a single unit — a
class.

• It restricts direct access to some of an object’s components, which means internal


details are hidden from outside.

• This is done to protect the data from unauthorized access and modification.

• Encapsulation is also called data hiding.

How Encapsulation is Achieved in Java?

• By declaring class variables as private (restricting direct access).

• Providing public getter and setter methods to access and update the value of private
variables.

• This controls how the data is accessed or modified.

Access Modifiers in Java

Access modifiers control the visibility (scope) of classes, variables, methods, and constructors.

Modifier Class Package Subclass World Description


(Anywhere)

private Yes No No No Accessible only within the same class

(default)* Yes Yes No No Accessible within the same package

protected Yes Yes Yes No Accessible within same package &


subclasses

public Yes Yes Yes Yes Accessible from anywhere


Advance Java – Module 1

* Default access modifier means no modifier is specified.

Example: Encapsulation with Access Modifiers

class Person {

// Private variables — cannot be accessed directly outside the class

private String name;

private int age;

// Public getter method for name

public String getName() {

return name;

// Public setter method for name

public void setName(String name) {

this.name = name;

// Public getter method for age

public int getAge() {

return age;

// Public setter method for age with validation

public void setAge(int age) {

if (age > 0) {
Advance Java – Module 1

this.age = age;

} else {

System.out.println("Invalid age!");

public class TestEncapsulation {

public static void main(String[] args) {

Person p = new Person();

// Using setter methods to set values

p.setName("Alice");

p.setAge(25);

// Using getter methods to access values

System.out.println("Name: " + p.getName());

System.out.println("Age: " + p.getAge());

// Trying to set invalid age

p.setAge(-5); // Output: Invalid age!

Output:

Name: Alice
Advance Java – Module 1

Age: 25

Invalid age!

Why Encapsulation is Important?

• Data Protection: Private variables protect internal object data from being corrupted.

• Control: Control over how variables are set or retrieved (validation logic in setters).

• Maintainability: Internal implementation can change without affecting external code.

• Flexibility: Easy to change one part of the code without affecting others.

• Reusability: Encapsulated code can be reused more safely.

Summary Table

Concept Description

Encapsulation Binding data & methods; hiding internal state.

private Restricts access to within the same class only.

public Allows access from anywhere.

protected Access within package and subclasses.

default (no modifier) Access only within the package.

Getter/Setter Public methods to access private fields safely.

6.6 Inheritance in Java

What is Inheritance?

• Inheritance is an OOP concept where a new class (called child or subclass) inherits
properties and behaviors (fields and methods) from an existing class (called parent or
superclass).

• It promotes code reusability and establishes a "is-a" relationship.

For example, a Dog "is a" Animal, so Dog class can inherit from Animal class.
Advance Java – Module 1

Benefits of Inheritance

• Code reuse — avoid duplication.

• Method overriding (modify inherited behavior).

• Polymorphism support.

• Logical class hierarchy organization.

Syntax

class ParentClass {

// fields and methods

class ChildClass extends ParentClass {

// additional fields and methods

Types of Inheritance in Java

1. Single Inheritance
One class inherits from one superclass.

class Animal {

void eat() {

System.out.println("Eating...");

}
Advance Java – Module 1

class Dog extends Animal {

void bark() {

System.out.println("Barking...");

2. Multilevel Inheritance
A class inherits from a subclass, forming a chain.

class Animal {

void eat() {

System.out.println("Eating...");

class Dog extends Animal {

void bark() {

System.out.println("Barking...");

class Puppy extends Dog {

void weep() {

System.out.println("Weeping...");

3. Hierarchical Inheritance
Multiple subclasses inherit from a single superclass.
Advance Java – Module 1

class Animal {

void eat() {

System.out.println("Eating...");

class Dog extends Animal {

void bark() {

System.out.println("Barking...");

class Cat extends Animal {

void meow() {

System.out.println("Meowing...");

Example: Multilevel Inheritance

class Animal {

void eat() {

System.out.println("Eating...");

class Dog extends Animal {


Advance Java – Module 1

void bark() {

System.out.println("Barking...");

class Puppy extends Dog {

void weep() {

System.out.println("Weeping...");

public class TestInheritance {

public static void main(String[] args) {

Puppy p = new Puppy();

p.eat(); // inherited from Animal

p.bark(); // inherited from Dog

p.weep(); // own method

Output:

Eating...

Barking...

Weeping...

Important Points
Advance Java – Module 1

• Java does not support multiple inheritance (a class cannot extend more than one class)
to avoid ambiguity (diamond problem).

• Use interfaces for multiple inheritance of type.

• Constructors of the parent class are not inherited, but can be called using super()
keyword.

• Child class inherits all non-private members of parent class.

• The keyword extends is used to inherit from a class.

Summary

Inheritance Type Description

Single Inheritance One class inherits from one superclass

Multilevel Inheritance Class inherits from subclass, creating chain

Hierarchical Inheritance Multiple subclasses inherit from one superclass

6.7 super Keyword in Java

Definition

• The super keyword in Java is a reference variable used to refer to the immediate parent
class object.

• It is commonly used to:

o Access parent class methods that are overridden in the child class.

o Access parent class fields if hidden by child class fields.

o Invoke the parent class constructor from a child class constructor.

Uses of super Keyword

Use Case Explanation Syntax Example

Access parent class Call a method in the parent class super.methodName();


method overridden by child
Advance Java – Module 1

Access parent class Refer to parent class field hidden super.fieldName;


field by child field

Call parent class Invoke parent class constructor super(parameters); (must be first
constructor from child constructor statement)

1. Using super to Access Parent Class Methods

If a child class overrides a parent method, you can call the parent version using super.

class Animal {

void sound() {

System.out.println("Animal makes a sound");

class Dog extends Animal {

void sound() {

System.out.println("Dog barks");

void parentSound() {

super.sound(); // Calls Animal's sound()

public class TestSuper {

public static void main(String[] args) {

Dog d = new Dog();


Advance Java – Module 1

d.sound(); // Dog barks

d.parentSound(); // Animal makes a sound

2. Using super to Access Parent Class Fields

If child class has a field with the same name as the parent, super accesses the parent’s field.

class Parent {

int num = 100;

class Child extends Parent {

int num = 200;

void display() {

System.out.println("Child num: " + num); // 200

System.out.println("Parent num: " + super.num); // 100

public class TestSuperField {

public static void main(String[] args) {

Child c = new Child();

c.display();

}
Advance Java – Module 1

3. Using super to Call Parent Class Constructor

You can call the parent’s constructor from the child constructor using super(). It must be the
first statement.

class Parent {

Parent() {

System.out.println("Parent constructor");

class Child extends Parent {

Child() {

super(); // Calls Parent constructor

System.out.println("Child constructor");

public class TestSuperConstructor {

public static void main(String[] args) {

Child c = new Child();

Output:

kotlin
Advance Java – Module 1

Parent constructor

Child constructor

Important Points

• super() calls the immediate parent class constructor.

• If you don’t explicitly call super(), Java inserts a no-arg super() automatically if available.

• super can only be used in instance methods or constructors, not in static context.

• Using super helps to access overridden methods or hidden fields.

Summary

Usage Description

super.method() Call parent class method overridden by child

super.field Access parent class field hidden by child

super() Call parent class constructor

6.8 Method Overriding in Java

What is Method Overriding?

• Method Overriding occurs when a subclass (child class) provides a specific


implementation of a method that is already defined in its superclass (parent class).

• The method in the subclass must have the same name, return type, and parameters as
the method in the superclass.

• It allows a subclass to modify or extend the behavior of an inherited method.

• Overriding is a key feature that enables runtime polymorphism (dynamic method


dispatch).

Rules for Method Overriding


Advance Java – Module 1

Rule Description

Method name and parameter Must be exactly the same as in the parent class
list

Return type Must be the same or a subtype (covariant return)

Access modifier Cannot be more restrictive than the parent method

Exceptions Can only throw the same or fewer checked exceptions

Cannot override final or static final methods cannot be overridden; static methods are
methods hidden, not overridden

Syntax

class Parent {

void display() {

System.out.println("Parent display");

class Child extends Parent {

@Override

void display() {

System.out.println("Child display");

Example

class Animal {

void sound() {
Advance Java – Module 1

System.out.println("Animal makes a sound");

class Dog extends Animal {

@Override

void sound() {

System.out.println("Dog barks");

public class TestOverride {

public static void main(String[] args) {

Animal a = new Animal();

a.sound(); // Animal makes a sound

Dog d = new Dog();

d.sound(); // Dog barks

Animal a2 = new Dog();

a2.sound(); // Dog barks — runtime polymorphism

Output:

Animal makes a sound


Advance Java – Module 1

Dog barks

Dog barks

Key Points

• @Override annotation (optional but recommended) helps the compiler check that you
are correctly overriding a method.

• Overriding happens at runtime; the JVM determines which method to call based on the
object type.

• This enables polymorphism, allowing the same method call to behave differently
depending on the object.

• You cannot override methods declared final or static (static methods are hidden, not
overridden).

• Access modifiers of the overriding method cannot be more restrictive (e.g., cannot
change public to private).

6.9 Polymorphism in Java

What is Polymorphism?

• Polymorphism means "many forms".

• In Java, polymorphism allows an entity (method or object) to take multiple forms.

• It enables a single interface or method to represent different underlying forms (data


types or classes).

• Polymorphism improves code flexibility and reusability.

Types of Polymorphism in Java

Type Description When It Happens How


Implemented
Advance Java – Module 1

Compile-time Method overloading — At compile time Method


(Static) multiple methods with the (method signature Overloading
Polymorphism same name but different resolved)
parameters.

Runtime Method overriding — subclass At runtime Method


(Dynamic) provides specific (method to call Overriding +
Polymorphism implementation of a parent determined) Inheritance
method.

1. Compile-time Polymorphism (Method Overloading)

• Multiple methods with the same name but different parameter lists (type, number, or
order).

• The compiler decides which method to call based on method signature.

Example:

class Calculator {

int add(int a, int b) {

return a + b;

double add(double a, double b) {

return a + b;

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

return a + b + c;

}
Advance Java – Module 1

public class TestOverloading {

public static void main(String[] args) {

Calculator calc = new Calculator();

System.out.println(calc.add(5, 10)); // 15

System.out.println(calc.add(3.5, 2.5)); // 6.0

System.out.println(calc.add(1, 2, 3)); // 6

2. Runtime Polymorphism (Method Overriding)

• When a subclass overrides a method of its superclass.

• The method to execute is determined at runtime based on the object's actual type (not
reference type).

• Supports dynamic method dispatch.

Example:

class Animal {

void sound() {

System.out.println("Animal makes a sound");

class Dog extends Animal {

@Override

void sound() {

System.out.println("Dog barks");
Advance Java – Module 1

class Cat extends Animal {

@Override

void sound() {

System.out.println("Cat meows");

public class TestPolymorphism {

public static void main(String[] args) {

Animal a;

a = new Dog();

a.sound(); // Dog barks

a = new Cat();

a.sound(); // Cat meows

a = new Animal();

a.sound(); // Animal makes a sound

Output:
Advance Java – Module 1

Dog barks

Cat meows

Animal makes a sound

How Runtime Polymorphism Works Internally?

• The JVM uses a virtual method table (vtable) for dynamic method dispatch.

• The actual method called depends on the runtime type of the object.

Key Points

Aspect Description

Compile-time polymorphism Method overloading; resolved by


compiler

Runtime polymorphism Method overriding; resolved at runtime


by JVM

Polymorphism enables Flexibility, code reuse, extensibility

Requires inheritance For runtime polymorphism

Allows treating subclass objects as superclass Promotes generalization


references

Summary Table

Polymorphism Description Example


Type

Compile-time Method overloading (same name, diff add(int, int) and add(double,
(Static) params) double)

Runtime (Dynamic) Method overriding in subclass Animal a = new Dog();


a.sound();
Advance Java – Module 1

6.10 Abstraction in Java

What is Abstraction?

• Abstraction is an OOP concept that focuses on hiding complex implementation details


and showing only the essential features of an object.

• It helps in reducing complexity and increasing efficiency.

• In Java, abstraction is achieved mainly through:

o Abstract Classes

o Interfaces

1. Abstract Class

• An abstract class is a class that cannot be instantiated directly.

• It can contain abstract methods (methods without a body) that must be implemented
by subclasses.

• It can also have concrete methods (methods with implementations).

• Used to provide a common base with some shared code and some methods to be
defined by subclasses.

Syntax

abstract class Animal {

abstract void sound(); // abstract method

void sleep() { // concrete method

System.out.println("Sleeping...");

class Dog extends Animal {


Advance Java – Module 1

void sound() {

System.out.println("Dog barks");

Example

abstract class Animal {

abstract void sound();

void sleep() {

System.out.println("Sleeping...");

class Dog extends Animal {

void sound() {

System.out.println("Dog barks");

public class TestAbstract {

public static void main(String[] args) {

// Animal a = new Animal(); // Error: Cannot instantiate abstract class

Dog d = new Dog();

d.sound(); // Dog barks

d.sleep(); // Sleeping...
Advance Java – Module 1

Output:

Dog barks

Sleeping...

2. Interface

• An interface is a reference type that can contain only abstract methods, default and
static methods (from Java 8), and constants.

• A class implements an interface and provides implementations for its abstract methods.

• Supports multiple inheritance of type (a class can implement multiple interfaces).

Syntax

java

interface Animal {

void sound(); // implicitly abstract

class Dog implements Animal {

public void sound() {

System.out.println("Dog barks");

}
Advance Java – Module 1

Example

java

interface Animal {

void sound();

class Dog implements Animal {

public void sound() {

System.out.println("Dog barks");

public class TestInterface {

public static void main(String[] args) {

Dog d = new Dog();

d.sound(); // Dog barks

Output:

Dog barks

Differences Between Abstract Class and Interface

Feature Abstract Class Interface


Advance Java – Module 1

Instantiation Cannot instantiate Cannot instantiate

Methods Can have abstract and Only abstract (before Java 8); default and
concrete methods static allowed after Java 8

Variables Can have instance variables Only constants (public static final)

Multiple Not supported Supported (a class can implement multiple


Inheritance interfaces)

Constructor Can have constructors Cannot have constructors

Use Case Shared code and common Define contract for classes
base

Summary

Concept Description

Abstraction Hiding internal details, showing essentials

Abstract Class Base class with abstract and concrete methods

Interface Pure abstraction with method declarations

Implement/Extend Class implements interface or extends abstract class

6.11 final Keyword in Java

What is the final Keyword?

• The final keyword in Java is used to declare constants, prevent method overriding, and
inheritance.

• It can be applied to:

o Variables (fields or local variables)

o Methods

o Classes
Advance Java – Module 1

1. final Variables

• A variable declared as final cannot be reassigned after it has been initialized.

• It effectively becomes a constant.

• If a final variable is not initialized at the point of declaration, it must be initialized in the
constructor (for instance variables).

Example:

class Constants {

final double PI = 3.14159; // constant

final int DAYS_IN_WEEK;

Constants() {

DAYS_IN_WEEK = 7; // final variable initialized in constructor

void display() {

System.out.println("PI = " + PI);

System.out.println("Days in a week = " + DAYS_IN_WEEK);

public class TestFinalVariable {

public static void main(String[] args) {

Constants c = new Constants();

c.display();
Advance Java – Module 1

// c.PI = 3.14; // Error: cannot assign a value to final variable PI

Output:

PI = 3.14159

Days in a week = 7

2. final Methods

• A method declared as final cannot be overridden by subclasses.

• It is used to prevent modification of method behavior in subclasses.

• Useful when you want to lock down certain methods.

Example:

class Parent {

final void show() {

System.out.println("Final method in Parent");

class Child extends Parent {

// void show() { // Error: Cannot override final method

// System.out.println("Trying to override");

// }

public class TestFinalMethod {


Advance Java – Module 1

public static void main(String[] args) {

Child c = new Child();

c.show(); // Output: Final method in Parent

3. final Classes

• A class declared as final cannot be subclassed.

• Used to prevent inheritance when you want to lock the class implementation.

• For example, String class is final in Java.

Example:

final class FinalClass {

void display() {

System.out.println("Final class method");

// class SubClass extends FinalClass { // Error: Cannot subclass final class

// }

public class TestFinalClass {

public static void main(String[] args) {

FinalClass obj = new FinalClass();

obj.display();

}
Advance Java – Module 1

Summary Table

Use of final Effect

final variable Value cannot be changed after initialization

final method Cannot be overridden by subclasses

final class Cannot be extended (no subclassing)

Important Notes

• final variables should be initialized once only.

• final method can still be overloaded, but not overridden.

• Marking a class final improves security and performance.

• final and static are often used together for constants, e.g., static final double PI =
3.14159;

6.12 Nested & Inner Classes in Java

What are Nested and Inner Classes?

• Nested Classes are classes defined within another class.

• They help logically group classes that are only used in one place, increase encapsulation,
and improve readability.

• There are two main types:

o Static Nested Classes

o Inner Classes (non-static nested classes)

Types of Nested Classes

Type Description
Advance Java – Module 1

Static Nested Nested class declared with static keyword. It can access only static members
Class of outer class.

Inner Class Non-static nested class that is associated with an instance of the outer class.
Can access all members, including private ones, of outer class.

Inner classes can be further divided into:

• Member Inner Class (non-static class inside another class)

• Local Inner Class (defined inside a method)

• Anonymous Inner Class (no name, used for quick implementation)

1. Static Nested Class

• Declared static inside an outer class.

• Does not have access to instance variables/methods of outer class directly.

• Can access only static members of outer class.

• Used when nested class functionality is related but does not need access to instance
data.

Syntax & Example:

class Outer {

static int data = 30;

static class StaticNested {

void display() {

System.out.println("Data from outer class: " + data);

public class TestStaticNested {


Advance Java – Module 1

public static void main(String[] args) {

Outer.StaticNested nested = new Outer.StaticNested();

nested.display();

Output:

Data from outer class: 30

2. Member Inner Class

• Defined inside a class without static modifier.

• Has access to all members (even private) of outer class.

• Associated with an instance of the outer class.

• To instantiate, first create an instance of the outer class.

Syntax & Example:

class Outer {

private int data = 10;

class Inner {

void display() {

System.out.println("Data from outer class: " + data);

public class TestInnerClass {


Advance Java – Module 1

public static void main(String[] args) {

Outer outer = new Outer();

Outer.Inner inner = outer.new Inner();

inner.display();

Output:

Data from outer class: 10

3. Local Inner Class

• Defined inside a method.

• Visible only within that method.

• Can access final or effectively final variables of the method.

Example:

class Outer {

void display() {

final int num = 100;

class LocalInner {

void print() {

System.out.println("Value of num: " + num);

LocalInner local = new LocalInner();


Advance Java – Module 1

local.print();

public class TestLocalInner {

public static void main(String[] args) {

Outer outer = new Outer();

outer.display();

Output:

Value of num: 100

4. Anonymous Inner Class

• Inner class without a name.

• Used to instantiate and override methods of a class or interface quickly.

• Commonly used in event handling, callbacks, etc.

Example:

abstract class Animal {

abstract void sound();

public class TestAnonymousInner {

public static void main(String[] args) {

Animal dog = new Animal() {


Advance Java – Module 1

void sound() {

System.out.println("Dog barks");

};

dog.sound();

Output:

Dog barks

Summary Table

Nested Class Description Access to Outer Class Instantiation


Type Members

Static Nested Static class inside outer Only static members Outer.StaticNested obj = new
Class class Outer.StaticNested();

Member Inner Non-static class inside All members, Outer.Inner obj = outer.new
Class outer class including private Inner();

Local Inner Class defined inside a Final/effectively final Inside method only
Class method method vars

Anonymous Class without name, Depends on parent Inline during instantiation


Inner Class instantiated on the spot class/interface

7. Packages and Access control:

7.1 Creating and Using Packages

Definition & purpose


Advance Java – Module 1

• A package is a namespace that groups related classes and interfaces.

• Packages help avoid name collisions, organize code, and control access (package-level
visibility).

• Common convention: reverse domain name (e.g. com.example.project).

How it maps to files / classpath

• If a class declares package com.example.util;, its .java file should live in


com/example/util/ relative to a source root.

• When compiling, either compile from the source root or use -d to specify an output
directory that preserves package directories.

• At runtime the JVM uses the classpath to locate package directories.

Syntax

package com.example.util; // must be top of file (except comments)

public class MyClass { ... }

You can use fully-qualified names instead of importing:

com.example.util.MyClass obj = new com.example.util.MyClass();

Rules / notes

• Top-level classes can be public or package-private (no modifier). They cannot be private
or protected.

• One public top-level class per .java file, and filename must match the public class name.

• import statements are optional (convenience) — you can always use fully-qualified
names.

• Wildcard import (import com.example.util.*;) imports types in that package only (not
subpackages).

Example — small project

Project layout:

project-root/

com/example/util/MathUtil.java
Advance Java – Module 1

com/example/util/Parent.java

com/example/app/Child.java

com/example/util/MathUtil.java

package com.example.util;

public class MathUtil {

public static final double PI = 3.141592653589793;

public static int add(int a, int b) { return a + b; }

// package-private (no modifier)

static int packageSecret() { return 42; }

// private

private static int privateSecret() { return -1; }

com/example/util/Parent.java

package com.example.util;

public class Parent {

public int publicField = 1;

protected int protectedField = 2;

int packageField = 3; // package-private

private int privateField = 4;

public int getPrivateField() { return privateField; }

}
Advance Java – Module 1

com/example/app/Child.java

package com.example.app;

import com.example.util.Parent;

import static com.example.util.MathUtil.PI; // static import example

import static com.example.util.MathUtil.add;

public class Child extends Parent {

public void showAccess() {

System.out.println("publicField = " + publicField); // OK

System.out.println("protectedField = " + protectedField); // OK (via inheritance)

// System.out.println("packageField = " + packageField); // COMPILE ERROR (package-


private)

// System.out.println("privateField = " + privateField); // COMPILE ERROR (private)

System.out.println("parentPrivateViaGetter = " + getPrivateField()); // OK

public static void main(String[] args) {

Child c = new Child();

c.showAccess();

System.out.println("PI via static import = " + PI);

System.out.println("add(2,3) via static import = " + add(2, 3));

// MathUtil.packageSecret(); // COMPILE ERROR if uncommented: packageSecret has


package access only

}
Advance Java – Module 1

Compile & run (from project-root)

javac com/example/util/*.java com/example/app/*.java

java com.example.app.Child

Expected output

publicField = 1

protectedField = 2

parentPrivateViaGetter = 4

PI via static import = 3.141592653589793

add(2,3) via static import = 5

Common pitfalls

• If you put package com.example.util; but don't place file in com/example/util/, javac will
complain if classpath/layout mismatch.

• Avoid mixing classes in the default package and named packages — classes in named
packages cannot import classes from the default package.

7.2 Access Modifiers

Four access levels for members/classes

1. public — accessible from anywhere (any package).

2. protected — accessible in same package and in subclasses (even if subclass is in a


different package). See the nuance below.

3. default (no modifier) — package-private: accessible only to classes in the same package.

4. private — accessible only inside the declaring class (but nested classes can access
private members of the outer class).

Top-level class modifiers

• A top-level class can be public or package-private (omit modifier). It cannot be private or


protected.
Advance Java – Module 1

Protected nuance (important)

• protected members are accessible to subclasses in other packages, but when accessed
from a subclass in a different package the access must be through the subclass (i.e.,
through this or through an expression whose type is the subclass). Accessing a protected
member through a superclass reference to an instance of the superclass from the
subclass in a different package is not allowed.

Example demonstrating the nuance:

// in package com.example.util

public class Parent {

protected int prot = 10;

// in package com.example.app

import com.example.util.Parent;

public class Child extends Parent {

void test() {

System.out.println(prot); // OK: accessed directly as subclass

Parent p = new Parent();

// System.out.println(p.prot); // COMPILE ERROR: cannot access protected via Parent ref


from different package

Access summary table (members accessed from another package)

• public → yes

• protected → yes if subclass (with the subclass-access nuance), otherwise no

• package-private (default) → no

• private → no
Advance Java – Module 1

Inner classes & private members

• Inner classes (non-static nested) and static nested classes inside the outer class can
access the outer class’s private members. Private is class-scoped (including nested
classes).

7.3 Importing Classes & Static Imports

import vs fully-qualified name

• import is compile-time convenience only. It lets you write List instead of java.util.List.

• You can always use java.util.List without an import.

Syntax

import com.example.util.MathUtil; // single-type import

import com.example.util.*; // on-demand import (types only)

Static import (since Java 5; available in Java 8)

• Lets you import static members (fields or methods) so you can reference them without
the class name.

import static java.lang.Math.PI;

import static java.lang.Math.*; // import all static members

• Use sparingly — static imports can hurt readability if overused.

Rules & gotchas

• import com.example.util.*; does not import subpackages (e.g.,


com.example.util.subpkg).

• import statements must appear after the package statement (if any) and before type
declarations.

• Static import only imports public and protected static members accessible from your
context.

Example (already shown above) — static import of PI and add:

import static com.example.util.MathUtil.PI;

import static com.example.util.MathUtil.add;


Advance Java – Module 1

System.out.println(PI);

System.out.println(add(2, 3));

When you don’t need import

• Types in java.lang (e.g., String, System) are implicitly imported.

• Nested classes can be referenced by Outer.Inner without import if Outer is accessible.

More examples & compiler error illustrations

Trying to access package-private from another package


If you uncomment the System.out.println("packageField = " + packageField); line in
Child.showAccess() you’ll get a compile error like:

error: packageField is not public in Parent; cannot be accessed from outside package

Trying to access private


If you try to access privateField directly you’ll see:

error: privateField has private access in Parent

Protected-access-through-superclass-reference error
If you do:

Parent p = new Parent();

System.out.println(p.protectedField);

from a subclass in a different package, javac will produce an error similar to:

error: protectedField has protected access in Parent

(While protectedField is accessible in the subclass when referenced directly as protectedField.)

1. A complete, pasteable Java 8 project folder (with build.sh / run.sh) so you can run and
test all package & access control examples.

2. Deep-dive expansions on:

o Package naming conventions


Advance Java – Module 1

o JARs & classpath basics

o Classloaders & package visibility

o Protected vs package-private nuances with more examples and exact compiler


output

Complete runnable Java 8 example project

Folder structure

java-packages-demo/

├── build.sh

├── run.sh

└── src/

└── com/

└── example/

├── util/

│ ├── MathUtil.java

│ └── Parent.java

└── app/

└── Child.java

src/com/example/util/MathUtil.java

package com.example.util;

public class MathUtil {

public static final double PI = 3.141592653589793;


Advance Java – Module 1

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

return a + b;

// package-private

static int packageSecret() {

return 42;

// private

private static int privateSecret() {

return -1;

src/com/example/util/Parent.java

package com.example.util;

public class Parent {

public int publicField = 1;

protected int protectedField = 2;

int packageField = 3; // package-private

private int privateField = 4;

public int getPrivateField() {

return privateField;

}
Advance Java – Module 1

src/com/example/app/Child.java

package com.example.app;

import com.example.util.Parent;

import static com.example.util.MathUtil.PI;

import static com.example.util.MathUtil.add;

public class Child extends Parent {

public void showAccess() {

System.out.println("publicField = " + publicField); // OK

System.out.println("protectedField = " + protectedField); // OK (via inheritance)

// System.out.println("packageField = " + packageField); // ERROR: package-private,


different package

// System.out.println("privateField = " + privateField); // ERROR: private access

System.out.println("parentPrivateViaGetter = " + getPrivateField()); // OK

public static void main(String[] args) {

Child c = new Child();

c.showAccess();

System.out.println("PI via static import = " + PI);

System.out.println("add(2,3) via static import = " + add(2, 3));


Advance Java – Module 1

// MathUtil.packageSecret(); // ERROR: package-private access not allowed here

build.sh

#!/bin/bash

mkdir -p out

javac -d out $(find src -name "*.java")

run.sh

#!/bin/bash

java -cp out com.example.app.Child

How to run

chmod +x build.sh run.sh

./build.sh

./run.sh

Expected output

publicField = 1

protectedField = 2

parentPrivateViaGetter = 4

PI via static import = 3.141592653589793

add(2,3) via static import = 5

Deep-dive expansions

A. Package naming conventions

• Reverse domain name: ensures uniqueness.


Example: com.google.gson, org.apache.commons.lang3

• Lowercase letters: avoids clashes with class names.


Advance Java – Module 1

• Subpackages: reflect logical module separation:

com.mycompany.project.model

com.mycompany.project.service

com.mycompany.project.util

• Avoid underscores and special characters: stick to letters/numbers.

B. JARs & classpath basics

• JAR (Java Archive): a .zip file containing .class files, resources, and a META-
INF/MANIFEST.MF.

• Compile to a JAR:

jar cvf mylib.jar -C out .

• Run from JAR:

o With Main-Class in manifest:

java -jar mylib.jar

o Without manifest, add JAR to classpath:

java -cp mylib.jar com.example.app.Child

• Multiple classpath entries:

java -cp "lib/*:out" com.example.app.Child

C. Classloaders & package visibility

• Bootstrap loader: loads java.* core classes from rt.jar in Java 8.

• Extension loader: loads JDK extension libraries from lib/ext.

• System loader: loads classes from the application classpath.

• Custom classloaders: can load classes dynamically from URLs, encrypted files, etc.

• Package-level visibility: If two classes with the same package name are loaded by
different classloaders, they are considered to be in different packages for access control.
Advance Java – Module 1

D. Protected vs package-private nuances

Same package:

package pkg1;

public class A {

protected int prot = 1;

int pkg = 2;

class B {

void test() {

A a = new A();

System.out.println(a.prot); // OK

System.out.println(a.pkg); // OK

Different package, subclass:

package pkg2;

import pkg1.A;

public class C extends A {

void test() {

System.out.println(prot); // OK via inheritance

A a = new A();

// System.out.println(a.prot); // ERROR: can't access via superclass ref

Compiler error message in Java 8:


Advance Java – Module 1

error: prot has protected access in A

System.out.println(a.prot);

8. Exception Handling:

8.1 Types of Exceptions (Checked, Unchecked, Errors)

Definition

• In Java, an exception is an event that disrupts the normal flow of a program during
execution.

• Java categorizes throwable objects into three main categories:

Hierarchy

java.lang.Object

└── java.lang.Throwable

├── java.lang.Exception → recoverable issues

│ ├── Checked Exceptions → must be declared/handled

│ └── Unchecked Exceptions (RuntimeException) → programmer errors or logic issues

└── java.lang.Error → serious system-level issues

Checked Exceptions

• Definition: Exceptions that the compiler forces you to handle with try-catch or declare
with throws.

• Examples: IOException, SQLException, ClassNotFoundException

• Purpose: Represent conditions that a reasonable application might want to catch.

Example

import java.io.*;

public class CheckedExample {


Advance Java – Module 1

public static void main(String[] args) {

try {

FileReader fr = new FileReader("nonexistent.txt"); // may throw FileNotFoundException

} catch (FileNotFoundException e) {

System.out.println("Checked Exception caught: " + e);

Output

Checked Exception caught: java.io.FileNotFoundException: nonexistent.txt (No such file or


directory)

If you remove the try-catch and don’t declare throws FileNotFoundException, javac gives:

error: unreported exception FileNotFoundException; must be caught or declared to be thrown

Unchecked Exceptions

• Definition: Exceptions that are subclasses of RuntimeException.

• Compiler does not require explicit handling.

• Examples: NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException

• Purpose: Typically programming mistakes.

Example

public class UncheckedExample {

public static void main(String[] args) {

int a = 5 / 0; // ArithmeticException at runtime

Output
Advance Java – Module 1

Exception in thread "main" java.lang.ArithmeticException: / by zero

Errors

• Definition: Subclasses of java.lang.Error.

• Not meant to be caught — represent serious problems that usually cannot be recovered
from.

• Examples: OutOfMemoryError, StackOverflowError

Example

public class ErrorExample {

public static void main(String[] args) {

// StackOverflowError due to infinite recursion

recurse();

static void recurse() {

recurse();

Output

Exception in thread "main" java.lang.StackOverflowError

Summary Table

Type Examples Compile-time Typical Cause


Check?

Checked IOException, SQLException Yes External conditions


Exception (files, DB)

Unchecked NullPointerException, No Logic/programming


Exception ArithmeticException errors
Advance Java – Module 1

Error OutOfMemoryError, No JVM/system-level


StackOverflowError failures

8.2 try, catch, finally

Definition

In Java, exceptions are handled using:

• try → Block of code where exceptions might occur.

• catch → Block to handle specific exceptions.

• finally → Block that always executes after try (and catch), regardless of whether an
exception occurred.

Syntax

try {

// risky code

} catch (ExceptionType1 e1) {

// handle exception type 1

} catch (ExceptionType2 e2) {

// handle exception type 2

} finally {

// cleanup code (executes regardless)

Rules

1. try must be followed by at least one catch or finally (or both).

2. finally is optional, but when present, runs even if:

o An exception is thrown and caught.

o An exception is thrown and not caught.


Advance Java – Module 1

o A return statement is executed in try or catch.

3. Only case when finally does not run: JVM exits (System.exit(0)) or a fatal error occurs.

Example 1 — Normal Execution

public class TryCatchFinallyDemo {

public static void main(String[] args) {

try {

System.out.println("Inside try block");

int result = 10 / 2; // no exception

System.out.println("Result = " + result);

} catch (ArithmeticException e) {

System.out.println("Caught: " + e);

} finally {

System.out.println("Finally block always runs");

Output

Inside try block

Result = 5

Finally block always runs

Example 2 — Exception Occurs & is Caught

public class TryCatchFinallyDemo2 {

public static void main(String[] args) {

try {
Advance Java – Module 1

System.out.println("Before risky code");

int result = 10 / 0; // throws ArithmeticException

System.out.println("This line won't run");

} catch (ArithmeticException e) {

System.out.println("Caught exception: " + e);

} finally {

System.out.println("Finally block executed");

Output

Before risky code

Caught exception: java.lang.ArithmeticException: / by zero

Finally block executed

Example 3 — Exception Not Caught

public class TryCatchFinallyDemo3 {

public static void main(String[] args) {

try {

String str = null;

System.out.println(str.length()); // NullPointerException

} catch (ArithmeticException e) {

System.out.println("Caught ArithmeticException");

} finally {

System.out.println("Finally still runs");

}
Advance Java – Module 1

Output

Finally still runs

Exception in thread "main" java.lang.NullPointerException

at TryCatchFinallyDemo3.main(TryCatchFinallyDemo3.java:6)

(Notice: finally ran before the uncaught exception terminated the program.)

Example 4 — Finally with return

public class TryCatchFinallyReturn {

public static void main(String[] args) {

System.out.println(method());

static int method() {

try {

return 1;

} finally {

System.out.println("Finally runs before method returns");

Output

Finally runs before method returns

1
Advance Java – Module 1

Example 5 — Finally skipped with System.exit

public class FinallySkipDemo {

public static void main(String[] args) {

try {

System.out.println("Exiting JVM");

System.exit(0);

} finally {

System.out.println("This will NOT run");

Output

Exiting JVM

8.3 Multiple Catch Blocks

Definition

• Multiple catch blocks allow you to handle different exception types separately after a
single try block.

• The first catch block whose parameter matches the thrown exception type (or a
superclass of it) will handle the exception — then control moves past all other catches.

Syntax

try {

// risky code

} catch (ExceptionType1 e1) {

// handle exception type 1

} catch (ExceptionType2 e2) {


Advance Java – Module 1

// handle exception type 2

} catch (Exception e) {

// generic handler (must be last)

Rules

1. Catch blocks are checked in order — more specific exceptions must come before more
general exceptions, otherwise compilation fails.

2. Only one catch block executes for a given exception.

3. From Java 7+, you can combine multiple exception types in a single catch using the
multi-catch feature:

catch (IOException | SQLException ex) {

// common handling

Example 1 — Separate catch blocks

public class MultipleCatchDemo {

public static void main(String[] args) {

try {

String s = null;

System.out.println(s.length()); // NullPointerException

int x = 10 / 0; // ArithmeticException (won't reach here)

} catch (ArithmeticException e) {

System.out.println("Caught ArithmeticException: " + e);

} catch (NullPointerException e) {

System.out.println("Caught NullPointerException: " + e);

} catch (Exception e) {

System.out.println("Caught generic Exception: " + e);


Advance Java – Module 1

Output

Caught NullPointerException: java.lang.NullPointerException

(Only the NPE catch block runs; ArithmeticException line is never reached.)

Example 2 — Wrong order causes compile error

public class WrongOrderCatch {

public static void main(String[] args) {

try {

int x = 10 / 0;

} catch (Exception e) { // <-- Too general

System.out.println("Generic exception");

} catch (ArithmeticException e) { // <-- Unreachable

System.out.println("Arithmetic exception");

Compilation error

error: exception ArithmeticException has already been caught

Example 3 — Multi-catch (Java 7+)

import java.io.*;

public class MultiCatchDemo {


Advance Java – Module 1

public static void main(String[] args) {

try {

if (args.length == 0) {

throw new IOException("No file provided");

} else {

throw new NullPointerException("Simulated NPE");

} catch (IOException | NullPointerException e) {

System.out.println("Caught: " + e);

Output (when run without args)

Caught: java.io.IOException: No file provided

Example 4 — Variable in multi-catch is final

In a multi-catch, the exception variable is implicitly final — you cannot reassign it.

public class MultiCatchFinalVar {

public static void main(String[] args) {

try {

throw new IOException("Test");

} catch (IOException | RuntimeException e) {

// e = new IOException(); // Compile error: variable e is final

System.out.println(e.getMessage());

}
Advance Java – Module 1

8.4 Nested try-catch

Definition

• A nested try-catch means putting a try block inside another try (or inside catch/finally).

• This is used when you want to handle different risky operations separately while still
being in a larger protected block.

• Common in file operations, database work, or multi-step tasks where each step may fail
independently.

Syntax

try {

// outer risky code

try {

// inner risky code

} catch (SpecificException e) {

// handle inner exception

} catch (GeneralException e) {

// handle outer exception

Rules

1. Inner try must have its own catch or finally.

2. An exception thrown in the inner try can be caught by the inner catch if it matches.

3. If the inner catch does not handle it, the exception propagates to the outer try-catch.

4. Nested try-catch can also appear inside a catch or finally block.


Advance Java – Module 1

Example 1 — Inner try handles exception

public class NestedTryDemo1 {

public static void main(String[] args) {

try {

System.out.println("Outer try start");

try {

int result = 10 / 0; // ArithmeticException

} catch (ArithmeticException e) {

System.out.println("Inner catch: " + e);

System.out.println("Outer try end");

} catch (Exception e) {

System.out.println("Outer catch: " + e);

Output

Outer try start

Inner catch: java.lang.ArithmeticException: / by zero

Outer try end

(Inner catch handled the exception, so outer catch never ran.)

Example 2 — Inner catch doesn’t handle, outer catch runs

public class NestedTryDemo2 {

public static void main(String[] args) {

try {
Advance Java – Module 1

System.out.println("Outer try start");

try {

String s = null;

System.out.println(s.length()); // NullPointerException

} catch (ArithmeticException e) {

System.out.println("Inner catch: " + e); // Won't catch NPE

System.out.println("Outer try end"); // Won’t run because NPE propagates

} catch (Exception e) {

System.out.println("Outer catch: " + e);

Output

Outer try start

Outer catch: java.lang.NullPointerException

Example 3 — Nested try inside catch

public class NestedTryInCatch {

public static void main(String[] args) {

try {

int[] arr = new int[3];

System.out.println(arr[5]); // ArrayIndexOutOfBoundsException

} catch (ArrayIndexOutOfBoundsException e) {

System.out.println("Outer catch: " + e);

try {
Advance Java – Module 1

int result = 10 / 0; // Another risky operation

} catch (ArithmeticException ex) {

System.out.println("Inner catch inside outer catch: " + ex);

Output

Outer catch: java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3

Inner catch inside outer catch: java.lang.ArithmeticException: / by zero

Example 4 — Nested try inside finally

public class NestedTryInFinally {

public static void main(String[] args) {

try {

System.out.println("Main try");

} catch (Exception e) {

System.out.println("Catch block");

} finally {

try {

String s = null;

System.out.println(s.length());

} catch (NullPointerException e) {

System.out.println("Handled inside finally: " + e);

}
Advance Java – Module 1

Output

Main try

Handled inside finally: java.lang.NullPointerException

8.5 Throwing Exceptions (throw keyword)

Definition

• The throw keyword is used inside a method or block to explicitly throw an exception
object.

• You can throw either:

o A checked exception (must be declared with throws in the method signature or


caught).

o An unchecked exception (subclass of RuntimeException) — no declaration


required.

Syntax

throw new ExceptionType("message");

Rules

1. You can throw only one exception at a time with throw.

2. The object after throw must be an instance of Throwable (Exception or Error).

3. If throwing a checked exception, you must:

o Handle it in a try-catch, or

o Declare it in the method with throws.

4. Throwing an unchecked exception does not require declaration.

Example 1 — Throwing a checked exception


Advance Java – Module 1

import java.io.IOException;

public class ThrowCheckedExample {

public static void main(String[] args) {

try {

readFile();

} catch (IOException e) {

System.out.println("Caught exception: " + e.getMessage());

static void readFile() throws IOException {

throw new IOException("File not found");

Output

Caught exception: File not found

Example 2 — Throwing an unchecked exception

public class ThrowUncheckedExample {

public static void main(String[] args) {

checkAge(15);

static void checkAge(int age) {

if (age < 18) {


Advance Java – Module 1

throw new IllegalArgumentException("Age must be 18 or above");

System.out.println("Access granted");

Output

Exception in thread "main" java.lang.IllegalArgumentException: Age must be 18 or above

at ThrowUncheckedExample.checkAge(ThrowUncheckedExample.java:6)

at ThrowUncheckedExample.main(ThrowUncheckedExample.java:3)

Example 3 — Throw inside catch

You can re-throw an exception (possibly wrapped in another exception):

public class RethrowExample {

public static void main(String[] args) {

try {

int result = 10 / 0;

} catch (ArithmeticException e) {

throw new RuntimeException("Calculation failed", e);

Output

Exception in thread "main" java.lang.RuntimeException: Calculation failed

at RethrowExample.main(RethrowExample.java:6)

Caused by: java.lang.ArithmeticException: / by zero

at RethrowExample.main(RethrowExample.java:3)
Advance Java – Module 1

Example 4 — Throwing in initializer

You can throw exceptions from constructors or static initializers:

public class ThrowInConstructor {

public ThrowInConstructor() throws Exception {

throw new Exception("Constructor failed");

public static void main(String[] args) {

try {

new ThrowInConstructor();

} catch (Exception e) {

System.out.println(e.getMessage());

Output

Constructor failed

8.6 Creating Custom Exceptions

Definition

A custom exception is a user-defined class that extends Exception or RuntimeException to


represent an application-specific error scenario.

Why create custom exceptions?

• To provide more meaningful and domain-specific error messages.


Advance Java – Module 1

• To separate application errors from Java's built-in exceptions.

• To make debugging easier by creating exceptions that clearly describe the problem.

Types of custom exceptions

1. Checked Custom Exception

o Extend the Exception class (but not RuntimeException).

o Must be declared in the throws clause or caught in a try-catch.

2. Unchecked Custom Exception

o Extend the RuntimeException class.

o Do not require declaration or mandatory handling.

Syntax

Checked

class MyCheckedException extends Exception {

public MyCheckedException(String message) {

super(message);

Unchecked

class MyUncheckedException extends RuntimeException {

public MyUncheckedException(String message) {

super(message);

Example 1 — Checked Custom Exception


Advance Java – Module 1

// Custom checked exception

class InvalidAgeException extends Exception {

public InvalidAgeException(String message) {

super(message);

public class CustomCheckedExample {

public static void main(String[] args) {

try {

register(15);

} catch (InvalidAgeException e) {

System.out.println("Error: " + e.getMessage());

static void register(int age) throws InvalidAgeException {

if (age < 18) {

throw new InvalidAgeException("You must be 18 or older to register.");

System.out.println("Registration successful!");

Output

Error: You must be 18 or older to register.


Advance Java – Module 1

Example 2 — Unchecked Custom Exception

// Custom unchecked exception

class NegativeBalanceException extends RuntimeException {

public NegativeBalanceException(String message) {

super(message);

public class CustomUncheckedExample {

public static void main(String[] args) {

withdraw(200, 100);

static void withdraw(int balance, int amount) {

if (amount > balance) {

throw new NegativeBalanceException("Insufficient funds: attempted to withdraw " +


amount);

System.out.println("Withdrawal successful!");

Output

Exception in thread "main" NegativeBalanceException: Insufficient funds: attempted to


withdraw 100

at CustomUncheckedExample.withdraw(CustomUncheckedExample.java:10)

at CustomUncheckedExample.main(CustomUncheckedExample.java:5)
Advance Java – Module 1

Example 3 — Custom Exception with extra fields

You can add extra data to a custom exception.

class OrderNotFoundException extends Exception {

private int orderId;

public OrderNotFoundException(int orderId, String message) {

super(message);

this.orderId = orderId;

public int getOrderId() {

return orderId;

public class OrderService {

public static void main(String[] args) {

try {

findOrder(101);

} catch (OrderNotFoundException e) {

System.out.println("Error: " + e.getMessage() + " | Order ID: " + e.getOrderId());

static void findOrder(int id) throws OrderNotFoundException {

throw new OrderNotFoundException(id, "Order not found in database");


Advance Java – Module 1

Output

Error: Order not found in database | Order ID: 101

8.7 throws keyword:

Definition

The throws keyword in Java is used in a method or constructor signature to declare the
exceptions that the method may throw during execution.
It acts as a warning to the caller:

"This method might throw this exception, so you need to handle it."

Purpose

• To tell the compiler and the calling method about possible exceptions.

• To propagate exceptions up the call stack instead of handling them inside the method.

• It’s required for checked exceptions (but optional for unchecked exceptions).

Syntax

returnType methodName(parameters) throws ExceptionType1, ExceptionType2, ... {

// method body

How it works

1. Method declaration includes throws to list possible exceptions.

2. Caller of the method must either:

o Handle the exception using try-catch

o OR declare throws again in its own method signature.


Advance Java – Module 1

Example 1 — Checked Exception with throws

import java.io.*;

public class ThrowsExample {

public static void main(String[] args) {

try {

readFile("data.txt");

} catch (IOException e) {

System.out.println("Error reading file: " + e.getMessage());

static void readFile(String fileName) throws IOException {

FileReader fr = new FileReader(fileName);

System.out.println("File opened successfully!");

fr.close();

Output (if file not found)

Error reading file: data.txt (No such file or directory)

Example 2 — Multiple Exceptions

public class MultipleThrowsExample {

public static void main(String[] args) {

try {
Advance Java – Module 1

process();

} catch (IOException | ClassNotFoundException e) {

System.out.println("Caught exception: " + e);

static void process() throws IOException, ClassNotFoundException {

if (Math.random() > 0.5) {

throw new IOException("I/O error occurred");

} else {

throw new ClassNotFoundException("Class not found");

Possible outputs

Caught exception: java.io.IOException: I/O error occurred

OR

Caught exception: java.lang.ClassNotFoundException: Class not found

Example 3 — With Custom Exception

class InvalidAgeException extends Exception {

public InvalidAgeException(String message) {

super(message);

}
Advance Java – Module 1

public class CustomThrowsExample {

public static void main(String[] args) {

try {

register(15);

} catch (InvalidAgeException e) {

System.out.println("Registration failed: " + e.getMessage());

static void register(int age) throws InvalidAgeException {

if (age < 18) {

throw new InvalidAgeException("Must be 18+ to register");

System.out.println("Registration successful!");

Output

Registration failed: Must be 18+ to register

Important Notes

• throws vs throw

o throw: used inside a method to actually throw an exception object.

o throws: used in method signature to declare possible exceptions.

• Checked Exceptions

o Must be declared with throws or handled with try-catch.

• Unchecked Exceptions
Advance Java – Module 1

o Can be declared, but it’s optional.

8.8 Try-with-resources (Java 7+)

Definition

Try-with-resources is a Java feature (introduced in Java 7) that automatically closes resources


(like files, database connections, streams) when the try block finishes — whether normally or
due to an exception.

A resource here means any object that implements the AutoCloseable interface (like Closeable
in I/O streams).

Why it’s useful

• No need for explicit finally blocks to close resources.

• Automatically handles exceptions during resource closing.

• Makes code shorter, cleaner, and less error-prone.

Syntax

try (ResourceType resource = new ResourceType()) {

// use the resource

} catch (ExceptionType e) {

// handle exception

• You can declare multiple resources inside the parentheses, separated by semicolons.

• Each resource must implement AutoCloseable (or Closeable).

How it works

1. The resource is opened in the try parentheses.


Advance Java – Module 1

2. After the try block ends (successfully or due to an exception), the resource’s close()
method is automatically called.

3. This happens before the catch block runs.

Example 1 — File Reading

import java.io.*;

public class TryWithResourcesExample {

public static void main(String[] args) {

try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {

String line;

while ((line = br.readLine()) != null) {

System.out.println(line);

} catch (IOException e) {

System.out.println("Error reading file: " + e.getMessage());

Output (if file contains)

Hello World

Java Try-with-resources

• Here, BufferedReader is closed automatically after the try block.

Example 2 — Multiple Resources

import java.io.*;
Advance Java – Module 1

public class MultipleResourcesExample {

public static void main(String[] args) {

try (

FileReader fr = new FileReader("input.txt");

BufferedReader br = new BufferedReader(fr)

){

System.out.println("First line: " + br.readLine());

} catch (IOException e) {

System.out.println("Error: " + e.getMessage());

Example 3 — Custom Resource

class MyResource implements AutoCloseable {

public void doSomething() {

System.out.println("Using resource");

@Override

public void close() {

System.out.println("Resource closed");

public class CustomResourceExample {


Advance Java – Module 1

public static void main(String[] args) {

try (MyResource res = new MyResource()) {

res.doSomething();

Output

Using resource

Resource closed

Exception Handling in Try-with-resources

• If both:

o The try block throws an exception, and

o The close() method throws an exception


→ The original exception from try is thrown, and the exception from close() is
suppressed.

• Suppressed exceptions can be retrieved using:

for (Throwable t : e.getSuppressed()) {

System.out.println(t);

Summary

1. Introduction to Java

• Java Overview – Java is a high-level, platform-independent, object-oriented


programming language known for "Write Once, Run Anywhere" (WORA) capability.

• History – Developed by Sun Microsystems (James Gosling, 1995), later acquired by


Oracle.
Advance Java – Module 1

• JDK, JRE, JVM –

o JDK (Java Development Kit): Contains tools to develop Java applications


(compiler, libraries, debugger).

o JRE (Java Runtime Environment): Contains JVM + libraries to run Java programs.

o JVM (Java Virtual Machine): Executes Java bytecode.

• Program Structure – Classes, methods, main() method, package declarations, imports.

• Compilation & Execution – javac compiles .java → .class bytecode → JVM executes.

2. Java Basics

• Syntax & Flow – Case-sensitive, class-based, follows top-down execution.

• Identifiers & Keywords – Identifiers (names for variables, methods, classes), keywords
(reserved words like class, public).

• Variables – Store data; constants declared with final.

• Data Types –

o Primitive: byte, short, int, long, float, double, char, boolean.

o Non-Primitive: Strings, arrays, classes, interfaces.

• Type Casting – Widening (implicit), narrowing (explicit).

• Operators – Arithmetic (+, -), relational (==, !=), logical (&&, ||), bitwise, assignment,
unary, ternary.

• Expressions & Precedence – Operator priority defines evaluation order.

• Comments – // single-line, /*...*/ multi-line, /**...*/ documentation.

3. Control Flow Statements

• Decision-making – if, if-else, switch.

• Loops – for, while, do-while, enhanced for-loop for arrays/collections.

• Jump Statements – break, continue, return.

• Nested Loops & Labels – Loops inside loops; labels allow breaking from specific loops.
Advance Java – Module 1

4. Arrays and Strings

• Arrays – Fixed-size, homogeneous data storage.

o Single-dimensional (int[] arr), multi-dimensional (int[][] matrix).

o Operations: cloning, sorting (Arrays.sort()), searching (Arrays.binarySearch()).

• Strings – Immutable sequences of characters; stored in the string pool.

• StringBuffer/StringBuilder – Mutable strings (Buffer → thread-safe, Builder → faster).

• Common Operations – concat, substring, toUpperCase, equals, trim, split.

5. Methods in Java

• Definition – Code block with a name, parameters, and return type.

• Parameter Passing – Always pass-by-value (objects pass reference value).

• Overloading – Multiple methods with same name but different parameters.

• Recursion – Method calls itself.

• Varargs – Accepts variable number of parameters (int... nums).

• main() Method – Entry point of Java application.

6. Object-Oriented Programming (OOP)

• Classes/Objects – Class defines blueprint; object is an instance.

• Constructors – Initialize objects; can be overloaded.

• this keyword – Refers to current object instance.

• static keyword – Belongs to class rather than object.

• Encapsulation – Private fields + public getters/setters.

• Inheritance – One class acquires properties of another.

• super keyword – Refers to parent class.

• Overriding – Redefining parent method in child.


Advance Java – Module 1

• Polymorphism – Compile-time (overloading), runtime (overriding).

• Abstraction – Hiding implementation (abstract classes, interfaces).

• final keyword – Prevent modification.

• Nested/Inner Classes – Classes inside classes.

7. Packages and Access Control

• Packages – Group related classes (package mypack;).

• Access Modifiers –

o public – Accessible everywhere.

o protected – Accessible in same package + subclasses.

o Default (no modifier) – Same package only.

o private – Same class only.

• Importing Classes – import packageName.ClassName; or import packageName.*;

• Static Imports – import static java.lang.Math.*;

8. Exception Handling

8.1 Types of Exceptions

• Checked Exceptions – Checked at compile-time (e.g., IOException).

• Unchecked Exceptions – Runtime exceptions (e.g., NullPointerException).

• Errors – Serious issues (e.g., OutOfMemoryError).

8.2 try-catch-finally

• try – Code that may throw exception.

• catch – Handles the exception.

• finally – Executes regardless of exception.

8.3 Multiple Catch Blocks

• Handle different exception types separately.


Advance Java – Module 1

8.4 Nested try-catch

• try-catch inside another try-catch.

8.5 throw keyword

• Manually throw an exception.

8.6 Custom Exceptions

• User-defined exceptions by extending Exception or RuntimeException.

8.7 throws keyword

• Declares exceptions a method may throw.

8.8 Try-with-resources (Java 7+)

• Automatically closes resources that implement AutoCloseable.

You might also like