JAVA PROGRAMMING
Complete Study Notes
UNIT 1
INTRODUCTION TO JAVA
History, Features & JDK Environment
Topics Covered
Introduction to Java • Features of Java • JDK Environment
OOP Concepts • Classes • Abstraction • Encapsulation
Inheritance • Polymorphism • Java vs C++ Comparison
1.1 What is Java?
Java is a high-level, object-oriented, platform-independent programming language developed by James
Gosling at Sun Microsystems in 1991. It was officially released to the public in 1995. Java was originally
called 'Oak' and later renamed 'Java'.
💡 Real-Life Analogy: Java is like the English language — it is understood everywhere.
You write code once in Java, and it runs on Windows, Mac, Linux, phones — everywhere
— without rewriting!
Quick Java Facts
Developed by → James Gosling at Sun Microsystems (now Oracle)
First released → 1995
Original name → 'Oak' (named after an oak tree outside Gosling's office)
Java motto → 'Write Once, Run Anywhere' (WORA)
Current owner → Oracle Corporation (acquired Sun Microsystems in 2010)
Latest version → Java 21 (LTS) — used in enterprise systems worldwide
Used in → Web apps, Android apps, banking software, games, NASA systems
1.2 Features of Java
Java has many powerful features that make it one of the most popular programming languages in the
world. These features are often remembered as the Java Buzzwords.
Simple
☕ Java is easy to learn and use. Its syntax is based on C++, but Java removed
complicated and confusing concepts like pointers, operator overloading, and
multiple inheritance. If you know basic C or C++, Java is very easy to pick up.
Object-Oriented
🎯 Java is based on the OOP model — everything is treated as an object. OOP makes
programs modular, easy to maintain, and reusable. Core OOP concepts: Classes,
Objects, Encapsulation, Inheritance, Polymorphism, Abstraction.
Platform Independent (WORA)
🌍 Java code is compiled into Bytecode (not machine code). This bytecode is then run
by the JVM (Java Virtual Machine) on ANY operating system. 'Write Once, Run
Anywhere' — same .class file runs on Windows, Linux, Mac, Android.
Secure
Java runs inside the JVM sandbox which prevents direct access to memory. There
🔒 are no pointers (major source of security holes). Java also provides a Security
Manager that controls what a program can access. Bytecode is verified before
execution.
Robust (Strong)
Java makes programs reliable by: (1) Strong type checking — variables must be
declared with a type. (2) Exception handling — errors are caught gracefully. (3)
Automatic Garbage Collection — no manual memory management. (4) No pointers
— eliminates memory corruption bugs.
Architecture Neutral
⚡ A Java .class (bytecode) file is NOT tied to any processor architecture. The same
file runs on 32-bit and 64-bit systems, Intel, ARM, and any processor. The JVM
handles the differences at runtime.
High Performance
🚀 Java uses JIT (Just-In-Time) Compiler which converts bytecode to native machine
code at runtime. This makes Java much faster than older interpreted languages.
Modern Java performance is very close to C/C++ in many benchmarks.
Multithreaded
Java has built-in support for multithreading — running multiple tasks
🔄 simultaneously. For example, a browser can download a file AND display a
webpage at the same time. Java provides Thread class and Runnable interface for
this.
Distributed
🔌 Java supports distributed computing — programs can run across multiple
computers on a network. Java provides classes like [Link] for network
communication, and technologies like RMI (Remote Method Invocation) for
distributed systems.
Portable
🌐 Because of platform independence and architecture neutrality, Java programs are
highly portable. A Java program on a Raspberry Pi behaves exactly the same as on
a Windows server — the JVM ensures consistent behavior.
Dynamic
⚙️ Java programs can adapt at runtime. Classes are loaded dynamically as needed
(not all at startup). Java supports reflection (inspecting classes at runtime) and
dynamic method dispatch (polymorphism).
Features Summary Table
Feature → What it means in simple words
Simple → Easy to learn, no pointers, clean syntax
Object-Oriented → Everything is an object — OOP principles
Platform Independent → WORA — same code runs everywhere via JVM/Bytecode
Secure → Sandbox, no pointers, bytecode verification
Robust → Exception handling, garbage collection, strong typing
Architecture Neutral → Bytecode works on any processor (32-bit/64-bit)
High Performance → JIT compiler speeds up execution
Multithreaded → Built-in support for parallel task execution
Distributed → Supports networked, multi-machine programs
Portable → Consistent behavior across all platforms
Dynamic → Classes loaded at runtime, supports reflection
1.3 How Java Achieves Platform Independence
This is the most important concept to understand about Java. Let's see what happens step by step when
you write and run a Java program.
Step-by-Step: Java Program Execution
STEP 1 → You write Java source code in a .java file (e.g., [Link])
STEP 2 → Java Compiler (javac) compiles it into BYTECODE (.class file)
Bytecode is NOT machine code — it is an intermediate language
STEP 3 → JVM (Java Virtual Machine) reads the .class file
STEP 4 → JVM translates bytecode to native machine code for THAT specific OS
STEP 5 → Program runs on Windows / Linux / Mac — same .class file!
[Link] →(javac)→ [Link] (Bytecode) →(JVM)→ Runs anywhere!
💡 Real-Life Analogy: Bytecode is like a recipe written in a universal language. A chef in
India, USA, or Japan reads the same recipe but uses local ingredients and equipment.
JVM is the 'local chef' — it reads the same bytecode but uses the local OS to execute it.
Language Compiled To Platform Requires
Dependent?
C / C++ Machine Code (.exe) YES — different .exe Recompile for each
for each OS OS
Java Bytecode (.class) NO — same .class JVM installed on target
everywhere system
Python Interpreted directly NO (mostly) Python interpreter
1.4 JDK Environment — JDK, JRE, JVM Explained
Beginners often get confused between JDK, JRE, and JVM. These three are nested inside each other —
JDK contains JRE, which contains JVM.
💡 Real-Life Analogy: Think of a car factory: JDK = entire factory (can build AND drive
cars). JRE = car with engine (can only drive, not build). JVM = just the engine (makes the
car move). You need the full factory (JDK) to develop Java programs.
▶ JVM — Java Virtual Machine
The JVM is a virtual computer that runs inside your real computer. It reads bytecode and executes it on
the actual hardware. JVM is platform-specific — there is a different JVM for Windows, Mac, and Linux —
but all JVMs read the same bytecode.
• Reads and executes .class (bytecode) files
• Provides memory management and Garbage Collection
• Provides security — runs in a sandbox
• Contains JIT (Just-In-Time) Compiler for faster execution
• Platform-specific — Windows JVM, Linux JVM, Mac JVM (different)
▶ JRE — Java Runtime Environment
JRE = JVM + Java Standard Libraries (APIs). If you just want to RUN a Java program (not develop one),
you only need JRE. It contains all the pre-written Java classes that programs use.
• JRE = JVM + Core Libraries ([Link], [Link], [Link], etc.)
• Needed by END USERS who only run Java programs
• Does NOT contain development tools like javac (compiler)
• Example: Running a Java-based game on your computer only needs JRE
▶ JDK — Java Development Kit
JDK = JRE + Development Tools. This is what DEVELOPERS install. It includes everything needed to
write, compile, debug, and run Java programs.
• JDK = JRE + javac (compiler) + javadoc + jar + debugger + jshell
• Needed by DEVELOPERS who write Java programs
• Download JDK from Oracle or OpenJDK
• Two editions: JDK SE (Standard), JDK EE (Enterprise), JDK ME (Mobile)
Component Full Name Contains Who Needs It
JVM Java Virtual Machine Bytecode executor, GC, Everyone (built-in)
JIT
JRE Java Runtime JVM + Standard Libraries End users (run only)
Environment
JDK Java Development Kit JRE + javac + tools Developers (build & run)
▶ Important JDK Tools
Tool Command What It Does
Java Compiler javac [Link] Converts .java source file to .class bytecode
Java Interpreter java Hello Runs the .class bytecode using JVM
Java Debugger jdb Hello Helps find and fix bugs in Java programs
JavaDoc Generator javadoc [Link] Generates HTML documentation from code
comments
JAR Tool jar cf [Link] *.class Packages multiple .class files into one .jar
archive
JShell jshell Interactive Java REPL — test code line by line
(Java 9+)
▶ First Java Program — Complete Explanation
⬤ ⬤ ⬤ Java
// This is a comment — ignored by compiler
public class Hello { // Class name MUST match filename
([Link])
public static void main(String[] args) { // Entry point of program
// ────── ────── ──── ─────────────
// public → accessible from anywhere
// static → belongs to class, not an object
// void → main() returns nothing
// main → JVM looks for this method to start
// String[] args → command-line arguments (array of strings)
[Link]("Hello, World!");
// System → built-in Java class
// out → output stream object
// println() → prints text and moves to next line
}
}
How to Compile and Run
Step 1: Save the file as [Link] (filename = class name)
Step 2: Open terminal/command prompt
Step 3: Compile: javac [Link] → Creates [Link]
Step 4: Run: java Hello → Output: Hello, World!
Common Mistake: File saved as '[Link]' but class is 'Hello' → Compilation error!
Java is CASE-SENSITIVE — 'Hello' and 'hello' are different!
OBJECT-ORIENTED PROGRAMMING (OOP)
Classes, Objects, Abstraction, Encapsulation, Inheritance, Polymorphism
2.1 What is OOP? — Overview of Programming Paradigms
A Programming Paradigm is a style or approach to writing programs. Different paradigms solve problems
in different ways.
Paradigm Approach Example Languages
Procedural / Program = sequence of steps (functions called C, Pascal, FORTRAN
Structured one by one)
Object-Oriented Program = collection of objects that interact with Java, C++, Python
(OOP) each other
Functional Program = set of mathematical functions (no Haskell, Lisp, Scala
state/variables)
Event-Driven Program reacts to user events (clicks, JavaScript, Visual
keystrokes) Basic
💡 Real-Life Analogy: Procedural programming = giving a robot step-by-step commands
(go forward, turn left, pick up box). OOP = creating intelligent robots (objects) that know
how to do their own jobs and interact with each other.
4 Main Pillars of OOP
1. Encapsulation → Wrapping data + methods together; hiding internal details
2. Abstraction → Showing only essential features; hiding complexity
3. Inheritance → One class acquires properties/methods of another class
4. Polymorphism → Same name, different behaviors depending on context
Memory tip: 'APIE' — Abstraction, Polymorphism, Inheritance, Encapsulation
2.2 Classes — The Blueprint
A Class is a user-defined data type (template/blueprint) that defines the structure and behavior of
objects. It groups related data (variables) and behavior (methods) together.
💡 Real-Life Analogy: A class is like a cookie cutter. The cookie cutter (class) is a
template. Each cookie you make with it is an object. All cookies have the same shape
(structure) but different fillings (data values).
A class contains:
• Instance Variables — data that each object stores (attributes/state)
• Methods — actions that objects can perform (behavior)
• Constructors — special methods that initialize objects when created
• Access Modifiers — control who can access the class members
⬤ ⬤ ⬤ Java
// Class Definition — the Blueprint
class Car {
// ── Instance Variables (Attributes) ──
String brand; // Brand name of the car
String color; // Color of the car
int speed; // Current speed in km/h
float fuelLevel; // Fuel level in liters
// ── Constructor (Initializes object) ──
Car(String b, String c, float f) {
brand = b;
color = c;
fuelLevel = f;
speed = 0; // Car starts with 0 speed
}
// ── Methods (Behaviors) ──
void accelerate(int amount) {
speed += amount;
[Link](brand + " now at " + speed + " km/h");
}
void brake() {
speed = 0;
[Link](brand + " stopped.");
}
void displayInfo() {
[Link]("Brand: " + brand + " | Color: " + color);
[Link]("Speed: " + speed + " | Fuel: " + fuelLevel + "
L");
}
}
class CarDemo {
public static void main(String[] args) {
Car c1 = new Car("Honda", "Red", 45.0f); // Object 1
Car c2 = new Car("Toyota", "Blue", 60.0f); // Object 2
[Link](60); // Honda now at 60 km/h
[Link](80); // Toyota now at 80 km/h
[Link](); // Honda stopped.
[Link]();
}
}
Understanding the Class Structure
class Car → Declares a new class named 'Car'
String brand → Instance variable — every Car object has its own brand
Car(String b...) → Constructor — automatically called when 'new Car()' is used
void accelerate() → Method — defines what a Car CAN DO
c1 and c2 → Two independent objects of class Car
[Link] → Dot operator accesses c1's specific brand value
2.3 Abstraction — Hiding Complexity
Abstraction means showing only the ESSENTIAL features of an object to the user and HIDING the
unnecessary internal details. The user knows WHAT something does, but not HOW it does it internally.
💡 Real-Life Analogy: When you drive a car, you only know: press accelerator to go,
press brake to stop. You do NOT need to know about fuel injection, piston movement, or
combustion. The car hides its complexity — that is abstraction!
In Java, abstraction is achieved using:
• Abstract Classes — classes that cannot be instantiated directly (partially abstract)
• Interfaces — 100% abstract; only method signatures, no implementation
▶ Abstract Class Example
⬤ ⬤ ⬤ Java
// Abstract class — cannot create object of Shape directly
abstract class Shape {
String color; // Concrete variable
// Abstract method — DECLARED here, DEFINED in subclasses
// No body {} — subclass MUST provide implementation
abstract double calculateArea();
// Concrete method — fully implemented (not abstract)
void displayColor() {
[Link]("Color: " + color);
}
}
// Circle provides the IMPLEMENTATION of calculateArea()
class Circle extends Shape {
double radius;
Circle(double r, String c) {
radius = r;
color = c;
}
@Override
double calculateArea() {
return 3.14159 * radius * radius; // Circle formula
}
}
// Rectangle provides its OWN implementation
class Rectangle extends Shape {
double length, width;
Rectangle(double l, double w, String c) {
length = l; width = w; color = c;
}
@Override
double calculateArea() {
return length * width; // Rectangle formula
}
}
class AbstractDemo {
public static void main(String[] args) {
// Shape s = new Shape(); // ERROR! Cannot create abstract object
Circle c = new Circle(5.0, "Red");
Rectangle r = new Rectangle(4.0, 6.0, "Blue");
[Link]("Circle Area : " + [Link]()); //
78.53
[Link]("Rectangle Area : " + [Link]()); //
24.0
[Link](); // Color: Red
[Link](); // Color: Blue
}
}
Key Rules of Abstract Class
Declared with 'abstract' keyword before 'class'
Cannot be instantiated (cannot use 'new AbstractClass()')
Can have abstract methods (no body) AND concrete methods (with body)
Subclass MUST implement ALL abstract methods (or itself be abstract)
Abstract class can have constructors, variables, static methods
If even ONE method is abstract → the class must be abstract
✅ Abstraction Benefit: The user calls calculateArea() without worrying about HOW it is
calculated for each shape. The formula is hidden inside each class. This makes code
clean, organized, and easy to change later.
2.4 Encapsulation — Data Hiding & Protection
Encapsulation means WRAPPING the data (variables) and methods that operate on that data into a
single unit (class), and RESTRICTING direct access to the data from outside.
💡 Real-Life Analogy: A medicine capsule: all the medicine is inside a protective shell.
You take the capsule — you don't touch the medicine directly. Similarly, encapsulation
puts data inside a class and protects it from direct access using private.
Encapsulation is achieved using:
• private variables — data cannot be accessed directly from outside the class
• public getter methods — allow controlled READING of the data
• public setter methods — allow controlled WRITING (with validation) of the data
⬤ ⬤ ⬤ Java
class BankAccount {
// private → ONLY accessible inside this class
private String holderName;
private long accountNumber;
private double balance;
// Constructor
BankAccount(String name, long accNo, double initialBalance) {
[Link] = name;
[Link] = accNo;
[Link] = initialBalance;
}
// ── GETTER methods — allow reading private data ──
public String getName() { return holderName; }
public long getAccNo() { return accountNumber; }
public double getBalance() { return balance; }
// ── SETTER with VALIDATION — controlled writing ──
public void deposit(double amount) {
if (amount > 0) { // Validation: no negative deposits
balance += amount;
[Link]("Deposited: ₹" + amount);
} else {
[Link]("Invalid amount!");
}
}
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) { // Can't withdraw more than
balance
balance -= amount;
[Link]("Withdrawn: ₹" + amount);
} else {
[Link]("Insufficient funds or invalid amount!");
}
}
}
class BankDemo {
public static void main(String[] args) {
BankAccount acc = new BankAccount("Rahul", 123456, 10000.0);
// [Link] = -5000; // ERROR! balance is private — direct
access blocked
[Link](5000); // ₹15000
[Link](3000); // ₹12000
[Link](20000); // Insufficient funds!
[Link]("Balance: ₹" + [Link]()); // ₹12000
}
}
Access Modifier Same Class Same Subclass Anywhere
Package
private ✅ Yes ❌ No ❌ No ❌ No
default (no modifier) ✅ Yes ✅ Yes ❌ No ❌ No
protected ✅ Yes ✅ Yes ✅ Yes ❌ No
public ✅ Yes ✅ Yes ✅ Yes ✅ Yes
Benefits of Encapsulation
Data Protection → Private variables cannot be corrupted from outside
Validation → Setter methods can check values before accepting them
Flexibility → Internal implementation can change without affecting other code
Maintainability → Easy to find and fix problems (all data in one place)
Reusability → Encapsulated classes can be reused safely in other programs
2.5 Inheritance — Code Reusability
Inheritance is the mechanism by which one class (child/subclass) ACQUIRES the properties (variables)
and behaviors (methods) of another class (parent/superclass). This promotes CODE REUSABILITY.
💡 Real-Life Analogy: A child inherits the eye color, height, and some behaviors from
their parents. Similarly, a child class inherits variables and methods from the parent class
— and can also add its own new features!
Syntax of Inheritance:
⬤ ⬤ ⬤ Java
class ParentClass {
// parent's variables and methods
}
class ChildClass extends ParentClass {
// 'extends' keyword creates inheritance
// Child gets all public/protected members of Parent
// Child can add its own new variables and methods
// Child can also OVERRIDE parent's methods
}
▶ Single Inheritance Example
⬤ ⬤ ⬤ Java
// Parent Class (Superclass)
class Animal {
String name;
int age;
void eat() {
[Link](name + " is eating.");
}
void breathe() {
[Link](name + " is breathing.");
}
}
// Child Class — inherits ALL public members of Animal
class Dog extends Animal {
String breed; // NEW variable added by Dog
void bark() { // NEW method added by Dog
[Link](name + " says: Woof Woof!");
}
void fetch() {
[Link](name + " fetches the ball!");
}
}
class InheritanceDemo {
public static void main(String[] args) {
Dog d = new Dog();
[Link] = "Bruno"; // Inherited from Animal
[Link] = 3; // Inherited from Animal
[Link] = "Labrador"; // Dog's own variable
[Link](); // Inherited method: Bruno is eating.
[Link](); // Inherited method: Bruno is breathing.
[Link](); // Dog's own method: Bruno says: Woof Woof!
[Link](); // Dog's own method: Bruno fetches the ball!
}
}
▶ Types of Inheritance in Java
Type Description Supported in Java?
Single One child inherits from one parent ✅ Yes
Multilevel A → B → C (chain of inheritance) ✅ Yes
Hierarchical Multiple children from one parent (A→B, A→C) ✅ Yes
Multiple One child inherits from TWO parents ❌ NO (via classes)
Hybrid Combination of above types ✅ Partially (via
interfaces)
⚠️ Note: Java does NOT support multiple inheritance through classes (to avoid the
'Diamond Problem'). However, a class can implement MULTIPLE INTERFACES to
achieve similar functionality.
▶ Multilevel Inheritance Example
⬤ ⬤ ⬤ Java
class Vehicle { // Level 1 (Grandparent)
void start() { [Link]("Vehicle started"); }
}
class Car extends Vehicle { // Level 2 (Parent)
void drive() { [Link]("Car is driving"); }
}
class SportsCar extends Car { // Level 3 (Child)
void turboBoost() { [Link]("Turbo boost activated!"); }
}
class MultiLevelDemo {
public static void main(String[] args) {
SportsCar sc = new SportsCar();
[Link](); // From Vehicle (Level 1)
[Link](); // From Car (Level 2)
[Link](); // Own method (Level 3)
}
}
▶ The super Keyword
'super' refers to the PARENT class. It is used to call parent's constructor or parent's overridden method
from inside the child class.
⬤ ⬤ ⬤ Java
class Person {
String name;
Person(String n) {
name = n;
[Link]("Person constructor: " + name);
}
void display() { [Link]("Person: " + name); }
}
class Student extends Person {
int rollNo;
Student(String n, int r) {
super(n); // Calls Person's constructor — MUST be first line
rollNo = r;
[Link]("Student constructor: roll " + rollNo);
}
@Override
void display() {
[Link](); // Calls Person's display()
[Link]("Roll No: " + rollNo);
}
}
class SuperDemo {
public static void main(String[] args) {
Student s = new Student("Rahul", 101);
[Link]();
}
}
Benefits of Inheritance
Code Reusability → Write code once in parent, reuse in all children
Less Redundancy → No need to repeat same methods in every class
Extensibility → Child adds new features without touching parent code
Method Overriding → Child can change parent behavior when needed
Polymorphism → Parent reference can hold child objects
2.6 Polymorphism — Many Forms, One Interface
Polymorphism means 'many forms'. It is the ability of ONE thing to behave DIFFERENTLY in different
situations. In Java, the same method name can behave differently based on context.
💡 Real-Life Analogy: A person is polymorphic! The same person behaves differently: as
a student in class, as a customer in a shop, as a son/daughter at home. Same entity —
different behavior. Java allows one method name to have multiple behaviors.
▶ Type 1: Compile-Time Polymorphism (Method Overloading)
Method Overloading = SAME method name, DIFFERENT parameters (different number or type). Java
decides which method to call at COMPILE TIME based on the arguments.
• Same method name
• Different number of parameters OR different types of parameters
• Resolved at compile time — also called Static Polymorphism / Early Binding
⬤ ⬤ ⬤ Java
class Calculator {
// Method 1: add TWO integers
int add(int a, int b) {
[Link]("Adding 2 ints:");
return a + b;
}
// Method 2: add THREE integers (same name, different count)
int add(int a, int b, int c) {
[Link]("Adding 3 ints:");
return a + b + c;
}
// Method 3: add TWO doubles (same name, different type)
double add(double a, double b) {
[Link]("Adding 2 doubles:");
return a + b;
}
// Method 4: concatenate two Strings (same name, String type)
String add(String a, String b) {
[Link]("Concatenating Strings:");
return a + b;
}
}
class OverloadDemo {
public static void main(String[] args) {
Calculator calc = new Calculator();
[Link]([Link](10, 20)); // → 30 (method 1)
[Link]([Link](10, 20, 30)); // → 60 (method 2)
[Link]([Link](3.5, 2.5)); // → 6.0 (method 3)
[Link]([Link]("Hello ", "World")); // → Hello World
(method 4)
// Java automatically picks the RIGHT method based on arguments!
}
}
▶ Type 2: Runtime Polymorphism (Method Overriding)
Method Overriding = Child class provides its OWN implementation of a method that is already defined in
the parent. Java decides which method to call at RUNTIME based on the actual object type.
• Same method name, same parameters as in parent
• Happens only in inheritance (parent-child relationship)
• Resolved at runtime — also called Dynamic Polymorphism / Late Binding
• @Override annotation is recommended (but not mandatory)
⬤ ⬤ ⬤ Java
class Animal {
void makeSound() {
[Link]("Animal makes a sound");
}
}
class Dog extends Animal {
@Override // Tells compiler: intentionally
overriding
void makeSound() {
[Link]("Dog says: Woof Woof!");
}
}
class Cat extends Animal {
@Override
void makeSound() {
[Link]("Cat says: Meow Meow!");
}
}
class Cow extends Animal {
@Override
void makeSound() {
[Link]("Cow says: Moo Moo!");
}
}
class PolymorphismDemo {
public static void main(String[] args) {
// Parent reference → Child object (Upcasting)
Animal a;
a = new Dog();
[Link](); // Woof Woof! (Dog's version called at runtime)
a = new Cat();
[Link](); // Meow Meow! (Cat's version called at runtime)
a = new Cow();
[Link](); // Moo Moo! (Cow's version called at runtime)
// Same method name (makeSound), different behavior — POLYMORPHISM!
// Java decides WHICH makeSound() to call based on the ACTUAL object
}
}
Feature Method Overloading Method Overriding
Also called Compile-time / Static Polymorphism Runtime / Dynamic Polymorphism
Where Same class Parent and Child class (inheritance)
Method name Same Same
Parameters DIFFERENT (count or type) SAME as parent
Return type Can differ Must be same (or covariant)
@Override Not needed Recommended
Resolved at Compile time Runtime (based on actual object)
2.7 Interface — 100% Abstraction
An Interface is a completely abstract type that contains only abstract method declarations (before Java 8)
and constants. A class IMPLEMENTS an interface — promising to provide the actual code for all
methods.
💡 Real-Life Analogy: An interface is like a job contract. The contract says: 'You MUST
be able to drive, code, and communicate.' It doesn't say HOW you drive — that depends
on the person (class) who signs the contract.
⬤ ⬤ ⬤ Java
// Interface declaration
interface Printable {
// All methods are public abstract by default
void print();
void preview();
}
interface Scannable {
void scan();
}
// A class can IMPLEMENT multiple interfaces (solves multiple inheritance!)
class MultiFunctionPrinter implements Printable, Scannable {
@Override
public void print() {
[Link]("Printing document...");
}
@Override
public void preview() {
[Link]("Showing print preview...");
}
@Override
public void scan() {
[Link]("Scanning document...");
}
}
class InterfaceDemo {
public static void main(String[] args) {
MultiFunctionPrinter mfp = new MultiFunctionPrinter();
[Link]();
[Link]();
[Link]();
}
}
Feature Abstract Class Interface
Keyword abstract class interface
Methods Abstract + Concrete both All abstract (before Java 8)
Variables Any type Only public static final (constants)
Constructor Can have Cannot have
Inheritance extend (one only) implement (multiple allowed)
Use when Partial implementation needed 100% abstraction / multiple types
C++ vs JAVA
Detailed Comparison — Key Differences for Exams
Both C++ and Java are object-oriented programming languages, but they differ significantly in design
philosophy, features, and execution. Java was designed to fix many problems of C++.
💡 Real-Life Analogy: C++ is like driving a manual car — very powerful and fast, but you
must manage the gears (memory) yourself. Java is like driving an automatic car — slightly
more overhead, but much safer and easier to manage.
3.1 Comprehensive C++ vs Java Comparison Table
Feature C++ Java
Platform Platform Dependent — different Platform Independent —
executable for each OS same .class runs everywhere
(JVM)
Compilation Compiled to native Machine Code Compiled to Bytecode (.class),
(.exe) interpreted by JVM
Pointers Supports pointers — programmer No pointers (except references) —
manages memory addresses safer, prevents corruption
Memory Mgmt Manual — programmer uses Automatic — JVM has Garbage
new/delete; memory leaks Collector, frees unused memory
possible
Multiple Inheritance Supported through classes directly NOT supported through classes;
achieved via interfaces
Operator Overloading Supported — redefine operators NOT supported — methods must
like +, -, * for custom types be used instead
Header Files Uses #include header files (e.g., No header files — uses import
#include <iostream>) statements (import [Link].*)
Preprocessor Has preprocessor directives No preprocessor directives
(#define, #ifdef, #include)
goto Statement Supported (but discouraged) NOT supported — removed to
improve code structure
Global Variables Supported — variables can exist NOT supported — all variables
outside all classes must be inside a class
Default Arguments Supported in function parameters NOT supported — use method
overloading instead
Structures & Unions Supported (struct, union NOT supported — only classes
keywords)
Templates Supported (Generic programming Generics supported (e.g.,
with templates) ArrayList<String>)
Exception Handling Supported (try/catch/throw) Built-in, more robust (checked +
unchecked exceptions)
Thread Support Not built-in — relies on Built-in — Thread class and
OS/external libraries Runnable interface
Security Less secure — direct memory More secure — sandbox, no direct
access possible memory access
Speed Faster — compiles directly to Slightly slower — extra JVM layer
native machine code (JIT improves this)
Portability Not portable — need to recompile Highly portable — Write Once Run
for each OS Anywhere (WORA)
Language Type Hybrid — supports both Pure OOP — everything must be
procedural and OOP inside a class
String char array or std::string Built-in String class — immutable
main() args int main(int argc, char* argv[]) public static void main(String[]
args)
Virtual Functions Explicit — declared with 'virtual' All non-static methods are virtual
keyword by default
Call by Reference Supported directly with & operator Objects passed by reference;
primitives by value
Documentation Doxygen-style comments Javadoc — automatic HTML
documentation generation
3.2 Key Points to Remember — Exam Focus
▶ Things Java REMOVED from C++ (and Why)
• Pointers removed → Prevents memory corruption and security vulnerabilities
• Multiple class inheritance removed → Avoids 'Diamond Problem' (ambiguity)
• Operator overloading removed → Prevents confusing and hard-to-read code
• goto removed → Improves code structure; use break/continue/return instead
• Header files removed → Cleaner code; everything in .java files
• Global variables removed → Enforces pure OOP; all code inside classes
• Structures/Unions removed → Classes cover all these use cases
• Manual memory management removed → Garbage Collector handles it automatically
▶ Things Java ADDED over C++ (Improvements)
• Garbage Collection → Automatic memory management, no memory leaks
• JVM & Bytecode → Platform independence (WORA)
• Built-in Multithreading → Thread class and Runnable interface included
• Built-in Security → Sandbox execution, bytecode verification
• Interfaces → Replaces multiple inheritance safely
• Exception Handling → More robust checked/unchecked exception system
• Reflection API → Inspect and manipulate classes at runtime
• JavaDoc → Auto-generate documentation from code comments
3.3 Complete OOP Concepts Quick Revision
Introduction to Java
Java created by James Gosling, Sun Microsystems, 1995. Motto: 'Write Once, Run Anywhere'
Key Features: Simple, OOP, Platform Independent, Secure, Robust, Multithreaded, Portable
How Java works: .java → (javac) → .class (Bytecode) → (JVM) → Runs on any OS
JVM = Java Virtual Machine — executes bytecode; platform-specific
JRE = JVM + Standard Libraries — for running Java programs
JDK = JRE + Development Tools (javac, jdb, jar) — for developers
main() must be: public static void main(String[] args)
OOP Concepts
OOP Paradigm: Treats program as collection of interacting objects
4 Pillars: Abstraction, Encapsulation, Inheritance, Polymorphism (APIE)
CLASS → Blueprint/Template with variables + methods (no memory)
OBJECT → Real instance of class created with 'new' (memory allocated in Heap)
ABSTRACTION → Hide complexity; show only essential details
→ Abstract classes (partial) + Interfaces (100% abstract)
ENCAPSULATION→ Wrap data + methods; use private + getters/setters
→ Data protection + validation through controlled access
INHERITANCE → Child gets parent's members using 'extends' keyword
→ Types: Single, Multilevel, Hierarchical (NOT Multiple via classes)
→ 'super' keyword calls parent constructor/method
POLYMORPHISM → One thing, many forms
→ Overloading: same name, diff params → Compile-time
→ Overriding: child redefines parent method → Runtime
C++ vs Java Key Points (Exam Highlights)
Java is Platform Independent; C++ is Platform Dependent
Java has NO pointers; C++ supports pointers
Java has Automatic Garbage Collection; C++ needs manual delete
Java does NOT support Multiple Inheritance via classes; C++ does
Java does NOT support Operator Overloading; C++ does
Java does NOT have Header Files; C++ uses #include
Java does NOT support global variables; C++ does
Java does NOT support goto; C++ does (though discouraged)
Java is more Secure; C++ allows direct memory access
Java is Slower (JVM overhead); C++ is Faster (native code)
Java has built-in Multithreading; C++ needs external libraries
UNIT 2
Unit: Java Programming Fundamentals
Structure of Java Program • Data Types • Variables • Operators • Keywords • Naming Conventions
From Scratch to Solid Foundation | Every Concept Explained with Examples
Unit Overview
This unit builds your complete foundation in Java. Everything in Java — from simple programs to
complex systems — rests on these six pillars. Understand them deeply and the rest of Java becomes
easy.
Topic What You Will Learn
1. Structure of a Java How every Java program is organised — from package to main method
Program
2. Data Types The 8 primitive types + String; sizes, ranges, and defaults
3. Variables What variables are, types of variables, scope and lifetime
4. Operators All 7 categories of operators with expressions and examples
5. Keywords All 50+ reserved words — what each one does
6. Naming Conventions Java's official style rules for classes, methods, variables, constants
1. Structure of a Java Program
1.1 The Minimal Java Program
Every Java program, no matter how simple or complex, follows the same skeleton. Here is the smallest
possible complete Java program — and every single line has a purpose:
// Line 1: package declaration (optional but recommended)
package [Link];
// Line 2: import statements (only when you need external classes)
import [Link];
// Line 3: class declaration — filename MUST match class name
public class HelloWorld {
// Line 4: main method — program execution starts HERE
public static void main(String[] args) {
// Line 5: your actual program logic
[Link]("Hello, World!");
} // end of main
} // end of class
Hello, World!
1.2 Every Line Explained — One by One
Line 1: package [Link];
A package is a named folder that organises your class files.
• Groups related classes together — just like folders on your desktop.
• Prevents naming conflicts — two companies can both have a class named User if they are in
different packages.
• Rule: Package names are always all lowercase: [Link]
• Optional: If you skip it, your class goes into the "default package" — fine for small practice
programs.
package myapp; // simple package
package [Link]; // professional reverse-domain style
Line 2: import [Link];
The import statement tells Java which external classes your code will use.
• Java has thousands of built-in classes spread across packages.
• Without import, you would have to type the full path every time: [Link] sc = new
[Link]([Link]);
• With import, you just write: Scanner sc = new Scanner([Link]);
• [Link].* is automatically imported — String, System, Math, Integer never need import.
import [Link]; // import one specific class
import [Link].*; // import ALL classes in [Link]
import [Link]; // for file reading
// [Link].* is ALWAYS auto-imported — no need to write it
Line 3: public class HelloWorld
The class is the fundamental building block of every Java program. Everything must be inside a class.
• public: The class is accessible from anywhere.
• class: Keyword that declares a class.
• HelloWorld: The name of this class.
• CRITICAL RULE: The filename MUST exactly match the public class name. Class HelloWorld →
file must be [Link]
• One .java file can have only ONE public class.
Line 4: public static void main(String[] args)
This is the entry point of every Java application. The JVM looks for this exact signature to start the
program. Let's dissect every word:
Word Meaning
public Accessible from anywhere — the JVM (which is external) must be able
to call it
static Belongs to the class itself, not to any object — so JVM can call it without
creating an object first
void This method returns nothing — it is the starting method, not a calculation
main The name the JVM specifically looks for — must be spelled exactly
'main'
String[] args An array of command-line arguments passed when running the program
(can be empty)
✖ If you change ANY part of this signature — e.g. remove static, or rename main to Main — the JVM will not
find it and the program will not run.
Line 5: [Link]("Hello, World!");
This prints text to the console. Let's break it down:
Part What It Is Meaning
System Class in [Link] Represents the running system — auto-
imported
out Static field An output stream connected to the console
println() Method Prints text followed by a newline character
"..." String literal The text to be displayed
[Link]("Hello"); // prints and moves to next line
[Link]("Hello"); // prints WITHOUT moving to next line
[Link]("%s is %d years old", "Alice", 25); // formatted print
// Output of println vs print:
[Link]("A");
[Link]("B");
[Link]("C"); // C is followed by newline
[Link]("D");
// Console shows: ABC
// D
1.3 Full Program Structure Template
//─────────────────────────────────────────────────────────
// SECTION 1: Package (first line, if used)
//─────────────────────────────────────────────────────────
package mypackage;
//─────────────────────────────────────────────────────────
// SECTION 2: Imports (after package, before class)
//─────────────────────────────────────────────────────────
import [Link];
import [Link];
//─────────────────────────────────────────────────────────
// SECTION 3: Class Declaration
//─────────────────────────────────────────────────────────
public class MyProgram {
//─────────────────────────────────────────────────────
// SECTION 4: Class-level fields (instance variables)
//─────────────────────────────────────────────────────
int instanceVariable = 10;
static int classVariable = 20;
//─────────────────────────────────────────────────────
// SECTION 5: main method — entry point
//─────────────────────────────────────────────────────
public static void main(String[] args) {
// local variables live here
int localVar = 30;
[Link]("Program running!");
}
//─────────────────────────────────────────────────────
// SECTION 6: Other methods
//─────────────────────────────────────────────────────
void myMethod() {
[Link]("Another method");
}
}
1.4 How Java Compiles and Runs
Java is unique because it compiles to an intermediate format — not directly to machine code. This is
what makes Java platform-independent ("Write Once, Run Anywhere").
Step 1: You write code in a .java file
[Link]
|
| javac [Link] ← Java Compiler
↓
Step 2: Compiler produces a .class file (bytecode)
[Link]
|
| java HelloWorld ← Java Virtual Machine (JVM)
↓
Step 3: JVM interprets bytecode and runs on your OS
OUTPUT: Hello, World!
KEY INSIGHT: .class bytecode runs on ANY OS that has a JVM.
Same .class file → Windows JVM, Mac JVM, Linux JVM — all work!
ℹ javac = Java Compiler. java = Java Virtual Machine launcher. These are the two commands you use in the
terminal.
2. Data Types
2.1 What Is a Data Type?
A data type tells Java what kind of value a variable can hold, how much memory to reserve, and what
operations are allowed on it.
Java has two broad categories of data types:
• Primitive types: 8 built-in basic types. They store the actual value directly in memory.
• Reference types: Classes, arrays, interfaces. They store a memory address (reference) to an
object.
Category Examples Stores
Primitive int, double, boolean, char, The actual value directly
byte, short, long, float
Reference / String, int[], Scanner, A memory address pointing to the object
Object ArrayList, any class
2.2 The 8 Primitive Data Types
These are the atoms of Java — everything else is built from them.
Type Size Range / Values Default Example
byte 1 byte (8 bits) -128 to 127 0 byte b = 100;
short 2 bytes (16 -32,768 to 32,767 0 short s = 5000;
bits)
int 4 bytes (32 -2,147,483,648 to 0 int n = 42;
bits) 2,147,483,647
long 8 bytes (64 -9.2×10^18 to 9.2×10^18 0L long l = 9876543210L;
bits)
float 4 bytes (32 ~6-7 decimal digits of 0.0f float f = 3.14f;
bits) precision
double 8 bytes (64 ~15-16 decimal digits of 0.0 double d = 3.14159;
bits) precision
char 2 bytes (16 0 to 65,535 (Unicode '\u0000' char c = 'A';
bits) characters)
boolean 1 bit (JVM true or false only false boolean flag = true;
decides)
💡 int is the most used type for whole numbers. double is the most used for decimals. Use long when your
number exceeds ~2 billion. Always add L suffix for long and f suffix for float literals.
2.3 Integer Types — Explained with Examples
byte smallAge = 25; // fits: 25 is within -128 to 127
short population = 30000; // fits: 30000 within ±32767
int salary = 95000; // most common integer type
long distance = 9460730472580L; // distance to nearest star in km, needs
L
// What happens when you exceed the range? — Overflow
byte overflow = 127;
overflow++; // 127 + 1 wraps around to -128!
[Link](overflow); // -128 (not 128!)
// Checking max and min values
[Link](Integer.MAX_VALUE); // 2147483647
[Link](Integer.MIN_VALUE); // -2147483648
[Link](Long.MAX_VALUE); // 9223372036854775807
-128
2147483647
-2147483648
9223372036854775807
2.4 Floating-Point Types — float vs double
// float needs 'f' suffix — without it Java assumes double
float pi1 = 3.14f; // 4 bytes — ~6-7 significant digits
double pi2 = 3.14159265; // 8 bytes — ~15-16 significant digits
[Link](pi1); // 3.14
[Link](pi2); // 3.14159265
// Precision difference
float result1 = 1.0f / 3.0f;
double result2 = 1.0 / 3.0;
[Link](result1); // 0.33333334 (less precise)
[Link](result2); // 0.3333333333333333 (more precise)
// Scientific notation
double big = 1.5e10; // 1.5 × 10^10 = 15,000,000,000
double small = 2.5e-4; // 2.5 × 10^-4 = 0.00025
💡 Always use double for calculations needing precision. Use float only when memory is extremely tight (e.g.
large graphics arrays).
2.5 char Type — Characters and Unicode
char letter = 'A'; // single quotes ONLY
char digit = '7'; // the character '7', NOT the number 7
char space = ' '; // space character
char newline = '\n'; // escape sequence for newline
char tab = '\t'; // escape sequence for tab
char unicode = '\u0041'; // Unicode for 'A' (hex 41 = decimal 65)
// char is internally a number — can do arithmetic!
char c = 'A';
[Link]((int) c); // 65 (ASCII/Unicode value of 'A')
[Link](c + 1); // 66 (promoted to int in arithmetic)
[Link]((char)(c + 1)); // B
// Loop through alphabet
for (char ch = 'A'; ch <= 'Z'; ch++) {
[Link](ch + " ");
}
// A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
2.6 Escape Sequences for char and String
Escape Character It Represents Example Output
Sequence
\n Newline — moves to next line Hello\nWorld → Hello (line break) World
\t Tab — inserts a horizontal tab A\tB → A B
\' Single quote 'Hello' → 'Hello'
\" Double quote She said \"Hi\" → She said "Hi"
\\ Backslash C:\\Users → C:\Users
\r Carriage return Moves cursor to start of line
\0 Null character String terminator (rarely used)
2.7 boolean Type
boolean isRaining = true;
boolean isSunny = false;
boolean isAdult = (age >= 18); // result of a comparison
if (isRaining) {
[Link]("Take an umbrella.");
} else {
[Link]("Enjoy the sunshine!");
}
// boolean from comparisons
int x = 10, y = 20;
boolean greater = (x > y);
boolean equal = (x == y);
[Link](greater); // false
[Link](equal); // false
2.8 Type Casting — Converting Between Types
Sometimes you need to convert a value from one type to another. Java has two kinds of conversion:
Type Direction Automatic? Risk
Widening Smaller type → Larger YES — Java does it None — no data loss
(Implicit) type automatically
(byte→int→long→double)
Narrowing Larger type → Smaller NO — you must cast Data loss possible —
(Explicit) type (double→int→byte) explicitly fractional part dropped
// Widening — automatic, no syntax needed
int i = 100;
long l = i; // int → long (automatic)
double d = i; // int → double (automatic)
[Link](d); // 100.0
// Narrowing — explicit cast required
double price = 99.95;
int rupees = (int) price; // cast double → int (drops .95)
[Link](rupees); // 99 (NOT rounded — just truncated)
// char ↔ int conversion
int ascii = 'A'; // widening: char → int
char letter = (char) 65; // narrowing: int → char
[Link](ascii); // 65
[Link](letter); // A
// String ↔ int conversion (NOT casting — use methods)
String s = "42";
int n = [Link](s); // String → int
String back = [Link](n); // int → String
⚠ (int) 99.95 gives 99, NOT 100. Casting truncates — it does NOT round. To round, use [Link](99.95)
which gives 100.
2.9 Widening Conversion Hierarchy
byte → short → int → long → float → double
↑
char
// Java auto-converts left-to-right (widening)
// You must manually cast right-to-left (narrowing)
byte b = 10;
short s = b; // auto
int i = s; // auto
long l = i; // auto
float f = l; // auto
double d = f; // auto
// Reverse direction — must cast
double d2 = 3.14;
float f2 = (float) d2;
long l2 = (long) f2;
int i2 = (int) l2;
short s2 = (short) i2;
byte b2 = (byte) s2;
3. Variables
3.1 What Is a Variable?
A variable is a named container in memory that holds a value. Think of it as a labelled box — the label
is the variable name, the box holds the value, and the box size (memory) depends on the data type.
// Syntax: dataType variableName = value;
int age = 20; // box named 'age' holds integer 20
double salary = 45000.50; // box named 'salary' holds decimal
String name = "Alice"; // box named 'name' holds text
boolean active = true; // box named 'active' holds boolean
3.2 Three Types of Variables
Variable Where Declared Scope Lifetime
Type
Local Inside a method or Only inside that Created when block starts,
Variable block method/block destroyed when block ends
Instance Inside class, outside Accessible via object of Lives as long as the object
Variable method the class lives
Static/Class Inside class with Accessible via class Lives as long as the program
Variable static keyword name — shared by all runs
objects
class Student {
// ── INSTANCE VARIABLES ── (one per object)
String name; // each Student has their own name
int age; // each Student has their own age
// ── STATIC / CLASS VARIABLE ── (ONE shared by all objects)
static int totalStudents = 0;
Student(String name, int age) {
[Link] = name;
[Link] = age;
totalStudents++; // shared counter increments for every new student
}
void display() {
// ── LOCAL VARIABLE ── (only exists inside this method)
String message = "Student: " + name + ", Age: " + age;
[Link](message);
// message is destroyed when display() returns
}
}
Student s1 = new Student("Alice", 20);
Student s2 = new Student("Bob", 22);
[Link]();
[Link]();
[Link]("Total students: " + [Link]);
Student: Alice, Age: 20
Student: Bob, Age: 22
Total students: 2
3.3 Variable Declaration Rules
• Must start with a letter, underscore (_), or dollar sign ($).
• Cannot start with a digit.
• Cannot be a Java keyword (int, class, for, etc.).
• Case-sensitive: age, Age, and AGE are three different variables.
• No spaces allowed in variable names.
• No limit on length, but keep names meaningful and short.
Valid Names Invalid Names Why Invalid
age 1age Starts with a digit
_name my name Contains a space
$price class Reserved keyword
totalMarks total-marks Hyphen not allowed
firstName [Link] Dot not allowed
3.4 final Variables — Constants
The final keyword makes a variable a constant — its value cannot be changed after it is assigned.
final int MAX_STUDENTS = 60;
final double PI = 3.14159;
final String SCHOOL_NAME = "ABC High School";
// Trying to change a final variable causes a compile error:
MAX_STUDENTS = 70; // ✖ ERROR: cannot assign a value to final variable
// CONVENTION: final variable names use ALL_CAPS with underscores
🔑 By convention, constant names (final variables) are written in ALL_CAPS_WITH_UNDERSCORES. This tells
every programmer reading the code that this value will never change.
3.5 var — Local Variable Type Inference (Java 10+)
// Before Java 10: you must explicitly write the type
ArrayList<String> list = new ArrayList<String>();
// Java 10+: 'var' lets the compiler infer the type
var list2 = new ArrayList<String>(); // type inferred as ArrayList<String>
var name = "Alice"; // type inferred as String
var age = 25; // type inferred as int
var price = 99.5; // type inferred as double
// var only works for LOCAL variables — NOT instance or static variables
// var CANNOT be used without an initialiser
var x; // ✖ ERROR — what type should x be?
4. Operators
An operator is a symbol that performs an operation on one or more values (operands). Java has 7
categories of operators.
4.1 Arithmetic Operators
Used for mathematical calculations.
Operator Name Expression Result
+ Addition 10 + 3 13
- Subtraction 10 - 3 7
* Multiplication 10 * 3 30
/ Division 10 / 3 3 (integer division — drops
remainder)
% Modulus 10 % 3 1 (the remainder after
division)
++ Increment i++ / ++i Increases i by 1
-- Decrement i-- / --i Decreases i by 1
int a = 10, b = 3;
[Link](a + b); // 13
[Link](a - b); // 7
[Link](a * b); // 30
[Link](a / b); // 3 ← integer division drops .33
[Link](a % b); // 1 ← remainder: 10 = 3×3 + 1
// For decimal division, cast one operand to double
[Link]((double)a / b); // 3.3333333333333335
// Increment: prefix vs postfix
int x = 5;
[Link](x++); // 5 (prints THEN increments → x becomes 6)
[Link](++x); // 7 (increments THEN prints → x was 6, now 7)
[Link](x); // 7
// Modulus use case: check even/odd
int n = 17;
if (n % 2 == 0) [Link]("Even");
else [Link]("Odd"); // Odd
13
7
30
3
1
3.3333...
5
7
7
Odd
4.2 Relational (Comparison) Operators
Compare two values and return true or false.
Operator Meaning Example Result
== Equal to 5 == 5 true
!= Not equal to 5 != 3 true
> Greater than 10 > 5 true
< Less than 3<8 true
>= Greater than or 5 >= 5 true
equal
<= Less than or equal 4 <= 3 false
int age = 18;
[Link](age == 18); // true
[Link](age != 18); // false
[Link](age >= 18); // true (used for adult check)
[Link](age > 21); // false
// Practical use in if statement
int marks = 75;
if (marks >= 90) [Link]("Grade A");
else if (marks >= 75) [Link]("Grade B");
else if (marks >= 60) [Link]("Grade C");
else [Link]("Grade D");
// Output: Grade B
✖ NEVER use == to compare String content. 5 == 5 works for primitives. For String objects, always
use .equals().
4.3 Logical Operators
Combine multiple boolean conditions.
Operator Name Rule Example
&& Logical AND true ONLY if BOTH sides (5>3) && (10>8) → true
are true
|| Logical OR true if AT LEAST ONE (5>3) || (10<8) → true
side is true
! Logical NOT Flips true to false and !(5>3) → false
false to true
int age = 25;
boolean hasLicense = true;
boolean hasInsurance = false;
// AND — both conditions must be true
if (age >= 18 && hasLicense) {
[Link]("Can drive");
}
// OR — at least one condition must be true
if (hasLicense || hasInsurance) {
[Link]("Has some road credential");
}
// NOT — flip the condition
if (!hasInsurance) {
[Link]("Warning: no insurance!");
}
// Combining all three
if (age >= 18 && hasLicense && !hasInsurance) {
[Link]("Can drive but needs insurance.");
}
Can drive
Has some road credential
Warning: no insurance!
Can drive but needs insurance.
Truth Tables
A B A && B A || B !A
true true true true false
true false false true false
false true false true true
false false false false true
4.4 Assignment Operators
Assign values to variables. The compound operators are shortcuts.
Operator Meaning Example Equivalent To
= Simple assignment x = 10 x = 10
+= Add and assign x += 5 x=x+5
-= Subtract and assign x -= 3 x=x-3
*= Multiply and assign x *= 2 x=x*2
/= Divide and assign x /= 4 x=x/4
%= Modulus and assign x %= 3 x=x%3
int x = 20;
[Link](x); // 20
x += 5; [Link](x); // 25
x -= 3; [Link](x); // 22
x *= 2; [Link](x); // 44
x /= 4; [Link](x); // 11
x %= 3; [Link](x); // 2 (11 % 3 = 2)
20
25
22
44
11
2
4.5 Bitwise Operators
Operate directly on binary (bit-level) representations of integers.
Operator Name Example (in binary) Result
& Bitwise AND 5 & 3 → 0101 & 0011 1
→ 0001
| Bitwise OR 5 | 3 → 0101 | 0011 → 7
0111
^ Bitwise XOR 5 ^ 3 → 0101 ^ 0011 → 6
0110
~ Bitwise NOT ~5 → ~00000101 → -6
11111010
<< Left shift 5 << 1 → 0101 << 1 → 10 (multiply by 2)
1010
>> Right shift 20 >> 2 → 10100 >> 2 5 (divide by 4)
→ 00101
>>> Unsigned right shift Same as >> but fills with Only for positive numbers
0
int a = 5; // binary: 0101
int b = 3; // binary: 0011
[Link](a & b); // 1 (0001)
[Link](a | b); // 7 (0111)
[Link](a ^ b); // 6 (0110)
[Link](~a); // -6
[Link](a << 1); // 10 (shift left = ×2)
[Link](a >> 1); // 2 (shift right = ÷2)
ℹ Bitwise operators are used in low-level programming, flag manipulation, networking, and encryption. For daily
Java code you rarely need them — but they appear in competitive programming.
4.6 Ternary Operator
A compact one-line if-else. Syntax: condition ? value_if_true : value_if_false
// Regular if-else (3 lines)
int age = 20;
String status;
if (age >= 18) {
status = "Adult";
} else {
status = "Minor";
}
// Same logic with ternary (1 line)
String status2 = (age >= 18) ? "Adult" : "Minor";
[Link](status2); // Adult
// More examples
int a = 15, b = 20;
int max = (a > b) ? a : b;
[Link]("Max = " + max); // Max = 20
int marks = 45;
String result = (marks >= 35) ? "Pass" : "Fail";
[Link](result); // Pass
Adult
Max = 20
Pass
4.7 instanceof Operator
Checks if an object is an instance of a specific class. Returns true or false.
String name = "Alice";
[Link](name instanceof String); // true
Object obj = "Hello";
if (obj instanceof String) {
String s = (String) obj; // safe to cast
[Link]([Link]()); // HELLO
}
// Useful in polymorphism before downcasting
Animal a = new Dog();
if (a instanceof Dog) {
Dog d = (Dog) a;
[Link]();
}
4.8 Operator Precedence — Order of Evaluation
When multiple operators appear in one expression, Java evaluates them in this order (higher = evaluated
first):
Priority Operators Associativity
1 (Highest) () [] . (method call) Left to right
2 ++ -- ~ ! (unary / prefix) Right to left
3 * / % Left to right
4 + - Left to right
5 << >> >>> Left to right
6 < > <= >= instanceof Left to right
7 == != Left to right
8 & (bitwise AND) Left to right
9 ^ (bitwise XOR) Left to right
10 | (bitwise OR) Left to right
11 && (logical AND) Left to right
12 || (logical OR) Left to right
13 ?: (ternary) Right to left
14 (Lowest) = += -= *= /= %= Right to left
// Without parentheses — uses precedence rules
int result = 2 + 3 * 4; // → 2 + 12 → 14 (* before +)
[Link](result); // 14
// With parentheses — overrides default precedence
int result2 = (2 + 3) * 4; // → 5 * 4 → 20
[Link](result2); // 20
// Complex expression
int x = 10;
int y = x++ + 2 * 3 - --x;
// Step 1: x++ returns 10 (x becomes 11)
// Step 2: 2*3 = 6
// Step 3: --x → x was 11, becomes 10; returns 10
// Step 4: 10 + 6 - 10 = 6
[Link](y); // 6
💡 When in doubt, use parentheses. They make code easier to read AND guarantee the order you intend. (2 +
3) * 4 is always clearer than relying on precedence.
5. Java Keywords
5.1 What Are Keywords?
Keywords are reserved words that Java has given a special built-in meaning. You cannot use them as
variable names, method names, or class names — they belong to Java.
ℹ Java has 51 reserved keywords (as of Java 17). Two of them — const and goto — are reserved but not
currently used. All keywords are lowercase.
5.2 Complete Keyword Reference
Data Type Keywords
Keyword What It Does
byte Declares an 8-bit integer variable
short Declares a 16-bit integer variable
int Declares a 32-bit integer variable (most common)
long Declares a 64-bit integer variable (needs L suffix on literals)
float Declares a 32-bit floating-point variable (needs f suffix)
double Declares a 64-bit floating-point variable (default for decimals)
char Declares a single 16-bit Unicode character
boolean Declares a variable that holds only true or false
void Specifies a method returns no value
Class and Object Keywords
Keyword What It Does
class Declares a new class
interface Declares an interface (a pure contract)
enum Declares an enumeration (a fixed set of constants)
extends Inherits from a parent class: class Dog extends Animal
implements Implements an interface: class Dog implements Runnable
new Creates a new object: new Dog()
this Refers to the current object — distinguishes instance var from local var
super Refers to the parent class — super() calls parent constructor
instanceof Tests if object is an instance of a class — returns boolean
abstract Declares an abstract class or method (incomplete, must be overridden)
final Makes variable constant, prevents method overriding, prevents
inheritance
static Belongs to the class itself, not to any specific object
Control Flow Keywords
Keyword What It Does
if Conditional — executes block if condition is true
else Executes block if the if condition is false
switch Multi-way branch — checks variable against multiple cases
case A single option in a switch statement
default The fallback case in switch (like else) — also default methods in
interface
break Exits a loop or switch block immediately
continue Skips the rest of the current iteration and goes to next
return Exits a method and optionally returns a value
for Loop that runs a set number of times
while Loop that runs while condition is true
do Part of do-while loop — runs at least once before checking condition
Exception Handling Keywords
Keyword What It Does
try Encloses risky code that might throw an exception
catch Handles a specific exception from the try block
finally Code that always runs after try-catch, whether exception occurred or not
throw Manually throws an exception object: throw new Exception('msg')
throws Declares that a method might throw an exception: void read() throws
IOException
Access & Modifier Keywords
Keyword What It Does
public Accessible from anywhere
private Accessible only within the same class
protected Accessible within same package and subclasses
synchronized Only one thread can execute this method/block at a time (thread-safety)
volatile Variable read directly from main memory — not cached by threads
transient Field is excluded from serialisation
native Method is implemented in another language (e.g. C) using JNI
strictfp Forces all floating-point calculations to follow IEEE 754 standard exactly
Package & Import Keywords
Keyword What It Does
package Declares which package this file belongs to (must be first line)
import Brings a class or package into scope so you don't need the full path
Other Important Keywords
Keyword What It Does
var Local variable type inference — compiler deduces the type (Java 10+)
record Declares an immutable data class with auto-generated getters (Java
16+)
sealed Restricts which classes can extend this class (Java 17+)
permits Used with sealed — lists which classes are allowed to extend
const Reserved but NOT used — use final instead
goto Reserved but NOT used — Java deliberately avoided goto
assert Checks a condition during testing — throws AssertionError if false
5.3 Keywords in Action — One Complete Example
package myapp; // package
public class BankAccount { // public, class
private double balance; // private
private static int totalAccounts = 0; // private, static
public final String BANK_NAME = "Java Bank"; // public, final
public BankAccount(double initialBalance) { // public, new (caller uses
new)
[Link] = initialBalance; // this
totalAccounts++;
}
public void deposit(double amount) { // public, void
if (amount <= 0) { // if
throw new IllegalArgumentException("Amount must be positive"); //
throw, new
}
balance += amount;
}
public double withdraw(double amount) throws Exception { // throws
try { // try
if (amount > balance) {
throw new Exception("Insufficient funds"); // throw, new
}
balance -= amount;
return balance; // return
} catch (Exception e) { // catch
[Link]([Link]());
return -1;
} finally { // finally
[Link]("Transaction complete.");
}
}
public static int getTotalAccounts() { // static
return totalAccounts; // return
}
}
6. Naming Conventions
6.1 Why Naming Conventions Matter
Java has an official set of naming conventions that every professional Java programmer follows. They
are not enforced by the compiler — your code will still run if you ignore them — but they are critical for:
• Readability — anyone can understand your code at a glance.
• Professionalism — every Java project worldwide follows these same rules.
• Collaboration — teams can read each other's code without confusion.
• Debugging — well-named variables reveal their purpose and prevent mistakes.
6.2 Naming Convention Rules — Complete Table
Identifier Convention Examples Avoid
Class name PascalCase — every Student, BankAccount, student, bankaccount,
word starts with HelloWorld, MyClass my_class
uppercase
Interface PascalCase — same Runnable, Serializable, runnable, iRunnable
name as class, often an Comparable, Drawable
adjective
Method name camelCase — first calculateArea(), getName(), CalculateArea(),
word lowercase, rest setAge(), printResult() calculate_area()
capitalised
Variable name camelCase — same studentName, totalMarks, StudentName,
as methods isActive, maxValue total_marks,
TOTALMARKS
Constant ALL_CAPS with MAX_SIZE, PI, maxSize, Pi,
name underscores DEFAULT_TIMEOUT, defaultTimeout
MIN_AGE
Package all lowercase, [Link], [Link], [Link]
name separated by dots [Link], [Link]
Enum name PascalCase for type, DayOfWeek { MONDAY, dayofweek { monday,
ALL_CAPS for TUESDAY, WEDNESDAY } tuesday }
values
6.3 PascalCase vs camelCase — Visualised
// PascalCase — First letter of EVERY word is uppercase
// Used for: Classes, Interfaces, Enums
class StudentRecord { }
class BankAccountManager { }
interface ShapeDrawable { }
// camelCase — First word all lowercase, rest capitalised
// Used for: Methods, Variables
int studentAge = 20;
double totalMarksObtained = 425.5;
boolean isAccountActive = true;
void calculateFinalGrade() { }
String getFirstName() { return firstName; }
// ALL_CAPS_WITH_UNDERSCORES — Every word uppercase, separated by _
// Used for: Constants (final variables)
final int MAX_RETRY_ATTEMPTS = 3;
final double GRAVITY_CONSTANT = 9.81;
final String DEFAULT_CURRENCY = "INR";
// [Link]
// Used for: Packages
package [Link];
package [Link];
6.4 Naming Rules with Good and Bad Examples
Class Names
// ✅ GOOD — PascalCase, noun, describes what the class represents
class Student { }
class BankAccount { }
class PaymentProcessor { }
class HttpRequestHandler { }
// ✖ BAD
class student { } // lowercase — looks like a variable
class bankaccount { } // no word boundaries — hard to read
class Bank_Account { } // underscores in class names — not Java style
class MyClass123 { } // numbers OK but meaningless
class C { } // too short — reveals nothing about purpose
Method Names
// ✅ GOOD — camelCase, verb or verb+noun, describes the action
void printReport() { }
double calculateTax(double income) { }
boolean isValidEmail(String email) { }
String getFullName() { }
void setAge(int age) { }
int getTotalStudentCount() { }
// ✖ BAD
void PrintReport() { } // starts uppercase — looks like a constructor
void print_report() { } // underscores — C style, not Java
void x() { } // meaningless name
void doStuff() { } // vague — what stuff?
Variable Names
// ✅ GOOD — camelCase, descriptive noun or adjective+noun
int studentAge = 20;
double accountBalance = 10500.75;
boolean isLoggedIn = false;
String firstName = "Alice";
int numberOfItemsInCart = 5;
// Acceptable short names in narrow scope (loop counters etc.)
for (int i = 0; i < 10; i++) { } // i is fine for a loop index
for (int row = 0; row < n; row++) { } // even better — descriptive
// ✖ BAD
int Age = 20; // starts uppercase — looks like a class
int a = 20; // too cryptic outside a small loop
int account_balance = 10500; // underscore — use camelCase
int x1, x2, x3; // what are these? use meaningful names
Constants
// ✅ GOOD — final + ALL_CAPS + underscores
public static final double PI = 3.14159265358979;
public static final int MAX_LOGIN_ATTEMPTS = 3;
public static final String DB_URL =
"jdbc:mysql://localhost/mydb";
public static final int HTTP_OK = 200;
// ✖ BAD
public static final double pi = 3.14; // all lowercase — not a
constant by look
public static final int maxAttempts = 3; // camelCase — can't tell it's a
constant
6.5 Special Naming Patterns
Pattern Convention Examples
Boolean Start with is, has, can, should isActive, hasPermission, canFly, shouldRetry
variables
Getter methods Start with get getName(), getAge(), getBalance()
Setter methods Start with set setName(), setAge(), setBalance(value)
Boolean getters Start with is or has isValid(), isEmpty(), hasChildren()
Factory methods Start with create or get or of createInstance(), of('value'), getInstance()
Abstract class Abstract (optional) AbstractShape, AbstractAnimal
prefix
Interface Adjective ending in -able or - Runnable, Iterable, Comparable, Serializable
convention ible
Test class names Class name + Test suffix StudentTest, BankAccountTest
6.6 Complete Naming Convention Example — One Full Class
// Package: all lowercase, dots as separators
package [Link];
// Class: PascalCase, meaningful noun
public class StudentRecord {
// Constants: ALL_CAPS_WITH_UNDERSCORES
public static final int MAX_MARKS = 100;
public static final int PASSING_MARKS = 35;
public static final String INSTITUTION = "ABC School";
// Instance variables: camelCase, descriptive
private String studentName;
private int rollNumber;
private double percentage;
private boolean isEnrolled;
// Static variable: camelCase
private static int totalEnrolled = 0;
// Constructor: same name as class (PascalCase)
public StudentRecord(String studentName, int rollNumber) {
[Link] = studentName;
[Link] = rollNumber;
[Link] = true;
totalEnrolled++;
}
// Getter method: camelCase, starts with get
public String getStudentName() { return studentName; }
public int getRollNumber() { return rollNumber; }
// Boolean getter: starts with is
public boolean isEnrolled() { return isEnrolled; }
// Setter method: camelCase, starts with set
public void setStudentName(String studentName) {
[Link] = studentName;
}
// Action method: camelCase verb, meaningful name
public String calculateGrade(int marksObtained) {
// Local variable: camelCase
double scorePercent = (double) marksObtained / MAX_MARKS * 100;
[Link] = scorePercent;
if (scorePercent >= 90) return "A+";
else if (scorePercent >= 75) return "A";
else if (scorePercent >= 60) return "B";
else if (scorePercent >= PASSING_MARKS) return "C";
else return "FAIL";
}
// Static method: camelCase
public static int getTotalEnrolled() { return totalEnrolled; }
}
7. Quick Revision — Exam Ready
7.1 Structure of Java Program — 5 Points
• Order in a file: package → import → class declaration → fields → main → other methods.
• File name MUST match public class name exactly (case-sensitive).
• main signature: public static void main(String[] args) — every word is mandatory.
• println() prints with newline, print() without, printf() with format.
• javac compiles .java → .class (bytecode). java runs the .class via JVM.
7.2 Data Types — 5 Points
• 8 primitives: byte, short, int, long (integers) + float, double (decimals) + char + boolean.
• Default values: int/byte/short/long → 0, float/double → 0.0, boolean → false, char → '\u0000'.
• Widening (auto): byte→short→int→long→float→double. Narrowing (explicit cast needed).
• long literals need L suffix: 9876543210L. float literals need f: 3.14f.
• Casting: (int)3.99 gives 3 — truncates, does NOT round.
7.3 Variables — 5 Points
• 3 types: local (inside method), instance (inside class, per-object), static (shared by all objects).
• Local variables MUST be initialised before use — no default value.
• final variables cannot be changed — use ALL_CAPS naming.
• var (Java 10+) lets compiler infer type: var x = 10; is same as int x = 10;
• Static variables are accessed via class name: [Link]
7.4 Operators — 5 Points
• 7 categories: Arithmetic, Relational, Logical, Assignment, Bitwise, Ternary, instanceof.
• Integer division: 10/3 = 3 (not 3.33). Use (double)10/3 for decimal result.
• x++ returns current value then increments. ++x increments then returns new value.
• Ternary: condition ? valueIfTrue : valueIfFalse — compact one-line if-else.
• Precedence (high→low): () → unary → * / % → + - → comparisons → && || → =
7.5 Common Exam Questions & Answers
Question Answer
What is the size of int in 4 bytes (32 bits), range: -2,147,483,648 to 2,147,483,647
Java?
What is the difference == compares references (memory). .equals() compares content. Always
between == use .equals() for Strings.
and .equals()?
Can a Java file have Yes, but only ONE can be public, and the file name must match that
multiple classes? public class.
What is the difference print() — no newline at end. println() — adds newline. printf() —
between print and formatted output.
println?
What is widening Automatic promotion from smaller to larger type: int → long → double.
conversion? No data loss.
What is narrowing Explicit cast from larger to smaller: (int)3.99 → 3. May lose data.
conversion?
What is the output of 3 — integer division. For 3.33, use (double)10/3.
10/3 in Java?
What is the difference x++ returns current value then increments. ++x increments first then
between x++ and ++x? returns.
What are the rules for Must start with letter, _, or $. Cannot be a keyword. Case-sensitive. No
variable names? spaces.
What is a final variable? A constant — once assigned, cannot be changed. Convention:
ALL_CAPS_WITH_UNDERSCORES.
What does static Belongs to the class, not to any object. Shared by all instances.
mean? Accessed via [Link].
What is the naming PascalCase — every word starts with uppercase: StudentRecord,
convention for a class? BankAccount.
What is the naming camelCase — first word lowercase, rest capitalised: calculateArea(),
convention for a getStudentName().
method?
What is the naming ALL_CAPS_WITH_UNDERSCORES: MAX_SIZE, PI,
convention for a DEFAULT_TIMEOUT.
constant?
8. One-Page Cheatsheet
Data Types
Type Size Literal Example
byte 1 byte byte b = 100;
short 2 bytes short s = 5000;
int 4 bytes int n = 42;
long 8 bytes long l = 99L;
float 4 bytes float f = 3.14f;
double 8 bytes double d = 3.14;
char 2 bytes char c = 'A';
boolean 1 bit boolean b = true;
Variables
Type Where Access
Local Inside method/block Only inside that block
Instance Inside class, outside method Via object: [Link]
Static Inside class with static Via class: [Link]
Operators
Category Symbols
Arithmetic + - * / % ++ --
Relational == != > < >= <=
Logical && || !
Assignment = += -= *= /= %=
Bitwise & | ^ ~ << >> >>>
Ternary condition ? a : b
instanceof obj instanceof ClassName
Naming Conventions
What Convention Example
Class / Interface PascalCase StudentRecord
Method / Variable camelCase calculateArea()
Constant (final) ALL_CAPS_UNDERSCORES MAX_SIZE
Package [Link] [Link]
Boolean variable isXxx / hasXxx isValid, hasPermission
Getter getXxx() getName()
Setter setXxx(value) setAge(20)
Program Structure Template
package mypackage; // 1. Package (optional, first line)
import [Link]; // 2. Imports (after package)
public class ClassName { // 3. Class (filename must match)
int instanceVar; // 4. Instance variable
static int classVar; // 5. Static variable
final int CONST = 10; // 6. Constant
public static void main(String[] args) { // 7. Entry point
int localVar = 5; // 8. Local variable
[Link](localVar);
}
void myMethod() { } // 9. Other methods
}
TOPIC 1
DECISION MAKING IN JAVA
Topics:
• Decision Making
• Looping
• Type Casting
• Classes & Objects
• Constructors
• Basic to Advanced
• Line-by-Line Code Explanations
• Real-Life Analogies
• Exam Ready
Decision making means: executing certain lines of code ONLY when a specific condition is true. Java
provides if, if-else, if-else-if, and switch statements for this.
🔸 Real-Life Analogy: Decision making is like traffic lights — Go (if condition is true), Stop
(if false). Your program takes different roads based on conditions.
1.1 The if Statement
The simplest decision: execute a block of code ONLY if the condition is TRUE. If the condition is false,
the block is completely skipped.
Syntax:
if (condition) {
// Code runs ONLY when condition is TRUE
}
Full Example with Explanation:
Java Code
class IfDemo {
public static void main(String[] args) {
int age = 20; // Declare a variable
if (age >= 18) { // Check condition: is age >= 18?
// This line runs ONLY if age >= 18 is TRUE
[Link]("You are eligible to vote!");
}
// Program continues here whether condition was true or false
[Link]("Program finished.");
}
}
Line-by-Line Explanation
int age = 20 → Creates a variable 'age' and stores 20 in it
if (age >= 18) → Checks: is 20 greater than or equal to 18?
{ ... } → This block executes ONLY when the condition is true
Since 20 >= 18 is TRUE → The message is printed
If age was 15 → Condition is FALSE, message is skipped entirely
✅ Output: You are eligible to vote! Program finished.
1.2 The if-else Statement
Use if-else when you want to do one thing if the condition is TRUE, and a different thing if it is FALSE.
Exactly ONE of the two blocks always runs.
Syntax:
if (condition) {
// Runs when condition is TRUE
} else {
// Runs when condition is FALSE
}
Java Code
class IfElseDemo {
public static void main(String[] args) {
int marks = 35;
if (marks >= 40) {
[Link]("Result: PASS"); // TRUE block
} else {
[Link]("Result: FAIL"); // FALSE block
}
}
}
How it Works
marks = 35, condition is: 35 >= 40 → FALSE
Since condition is FALSE → the else block runs
Output: Result: FAIL
Change marks = 50 → 50 >= 40 is TRUE → Output: Result: PASS
Only ONE block ever runs — never both
1.3 The if-else-if Ladder (Multiple Conditions)
Use this when you have MORE than two possible outcomes. Java checks conditions one by one from top
— as soon as one is TRUE, that block runs and the rest are skipped.
🔸 Real-Life Analogy: Like a grading system: check if marks >= 90 (A), else if >= 80 (B),
else if >= 70 (C)... only one grade applies.
Java Code
class GradeSystem {
public static void main(String[] args) {
int marks = 75;
if (marks >= 90) {
[Link]("Grade: A (Excellent)");
} else if (marks >= 80) { // Only checked if first is FALSE
[Link]("Grade: B (Very Good)");
} else if (marks >= 70) { // Only checked if above two are
FALSE
[Link]("Grade: C (Good)");
} else if (marks >= 60) {
[Link]("Grade: D (Average)");
} else { // Runs if ALL conditions above
are FALSE
[Link]("Grade: F (Fail)");
}
}
}
✅ Output: Grade: C (Good) [because 75 >= 70 is true, all previous were false]
1.4 Nested if Statement
An if inside another if is called nested if. The inner if is checked only when the outer if is true.
Java Code
class NestedIfDemo {
public static void main(String[] args) {
int age = 20;
boolean hasVoterID = true;
if (age >= 18) { // Outer if
if (hasVoterID == true) { // Inner if — only checked if
outer is true
[Link]("You can vote!");
} else {
[Link]("Get a Voter ID first.");
}
} else {
[Link]("You are too young to vote.");
}
}
}
1.5 The switch Statement
Switch is used when you want to compare ONE variable against MANY fixed values. It is cleaner and
faster than a long if-else-if chain.
🔸 Real-Life Analogy: Like a TV remote — you press button 1, 2, 3, etc. Each button does
something different. Switch checks which 'button' (case) matches and runs that block.
Syntax:
switch (variable) {
case value1:
// Code for value1
break; // MUST have break to exit switch
case value2:
// Code for value2
break;
default:
// Runs if NO case matches (like the 'else')
}
Java Code
class SwitchDemo {
public static void main(String[] args) {
int day = 3; // We want to find the name for day number 3
switch (day) { // Switch on the value of 'day'
case 1:
[Link]("Monday");
break; // Exit the switch — prevents fall-through
case 2:
[Link]("Tuesday");
break;
case 3: // day == 3 → this matches!
[Link]("Wednesday");
break;
case 4:
[Link]("Thursday");
break;
case 5:
[Link]("Friday");
break;
default: // Runs if day is NOT 1,2,3,4, or 5
[Link]("Weekend!");
}
}
}
Important Points about switch
break statement → Stops execution from falling into the next case
default → Optional; runs when no case matches (like else)
switch works with → int, char, String, byte, short (NOT float or double)
Without break → ALL cases below the matching case also run (fall-through!)
What happens WITHOUT break? (Fall-through):
Java Code
int x = 2;
switch (x) {
case 1: [Link]("One");
case 2: [Link]("Two"); // Matches here
case 3: [Link]("Three"); // Also runs! (no break above)
case 4: [Link]("Four"); // Also runs!
}
// Output: Two Three Four (all cases after match run!)
Feature if-else switch
Condition Type Any boolean expression Only equality check (==)
Data Types All types int, char, String only
Use When Range checks (>= , <=) Fixed value checks (== )
Speed Slower for many conditions Faster for many fixed values
Readability Can get complex Cleaner for many options
TOPIC 2
LOOPING IN JAVA
A loop repeats a block of code multiple times without writing it again and again. Java has four types of
loops: for, while, do-while, and for-each.
🔸 Real-Life Analogy: A loop is like a washing machine cycle — it runs the wash, rinse,
spin process repeatedly until the cycle is complete.
2.1 The for Loop
The for loop is used when you know in advance HOW MANY TIMES to repeat. It is the most commonly
used loop in Java.
Syntax:
for (initialization ; condition ; update) {
// Code to repeat
}
initialization → Runs ONCE at the start (set up counter variable)
condition → Checked BEFORE every loop. If false, loop stops.
update → Runs AFTER every iteration (usually i++ or i--)
Java Code
class ForLoopDemo {
public static void main(String[] args) {
// Print numbers 1 to 5
for (int i = 1; i <= 5; i++) {
// ───────── ────── ───
// init: i=1 cond. update: i becomes i+1 after each round
[Link]("Count: " + i);
}
[Link]("Loop finished!");
}
}
Step-by-Step Execution Trace
Step 1 → i = 1 (initialization, runs once)
Step 2 → Is 1 <= 5? YES → print 'Count: 1' → i++ → i = 2
Step 3 → Is 2 <= 5? YES → print 'Count: 2' → i++ → i = 3
Step 4 → Is 3 <= 5? YES → print 'Count: 3' → i++ → i = 4
Step 5 → Is 4 <= 5? YES → print 'Count: 4' → i++ → i = 5
Step 6 → Is 5 <= 5? YES → print 'Count: 5' → i++ → i = 6
Step 7 → Is 6 <= 5? NO → Loop STOPS
Example — Sum of Numbers 1 to 10:
Java Code
class SumExample {
public static void main(String[] args) {
int sum = 0; // Holds running total
for (int i = 1; i <= 10; i++) {
sum = sum + i; // Add current i to sum
// i=1: sum=1, i=2: sum=3, i=3: sum=6 ... i=10: sum=55
}
[Link]("Sum = " + sum); // Output: Sum = 55
}
}
Example — Multiplication Table:
Java Code
class TableExample {
public static void main(String[] args) {
int n = 5; // Print table of 5
for (int i = 1; i <= 10; i++) {
[Link](n + " x " + i + " = " + (n * i));
}
// Output: 5 x 1 = 5
// 5 x 2 = 10 ... 5 x 10 = 50
}
}
2.2 The while Loop
The while loop is used when you do NOT know in advance how many times to repeat. It keeps running
as long as the condition is true.
🔸 Real-Life Analogy: While loop is like eating food — you keep eating while you are still
hungry. You don't know in advance how many bites it takes.
Syntax:
while (condition) {
// Repeats as long as condition is TRUE
// Must update something inside or it becomes infinite loop!
}
⚠ Condition is checked BEFORE entering the loop each time
Java Code
class WhileDemo {
public static void main(String[] args) {
int i = 1; // Initialize counter BEFORE the loop
while (i <= 5) { // Check condition first
[Link]("Number: " + i);
i++; // Update counter — MUST do this or infinite
loop!
}
[Link]("Done!");
}
}
⚠️Important: Always update the variable inside while loop! If i++ is missing, the condition
never becomes false and the loop runs FOREVER (infinite loop) — crashing your program!
Practical Example — ATM PIN Check:
Java Code
class ATMExample {
public static void main(String[] args) {
int correctPIN = 1234;
int enteredPIN = 0;
int attempts = 0;
// Keep asking until correct PIN or 3 attempts
while (enteredPIN != correctPIN && attempts < 3) {
[Link]("Enter PIN:");
enteredPIN = 1234; // Simulating input (correct on first try)
attempts++;
}
if (enteredPIN == correctPIN) {
[Link]("Access Granted!");
} else {
[Link]("Card Blocked!");
}
}
}
2.3 The do-while Loop
The do-while loop is similar to while BUT it executes the body FIRST, then checks the condition. This
means the body runs AT LEAST ONCE even if the condition is false.
🔸 Real-Life Analogy: do-while is like trying food for the first time — you eat it first (do),
then decide if you want more (while). You always eat at least one bite.
Syntax:
do {
// Code runs at least ONCE — then condition is checked
} while (condition); // ← Note the semicolon here!
Java Code
class DoWhileDemo {
public static void main(String[] args) {
int i = 1;
do {
[Link]("Value: " + i); // Runs FIRST
i++;
} while (i <= 5); // THEN check condition
// Even if i starts at 10 (> 5), body runs once:
int x = 10;
do {
[Link]("This runs once: x = " + x);
} while (x < 5); // FALSE immediately, but body already ran!
}
}
Feature for loop while loop do-while
loop
Use when Know exact Count unknown Must run at
count least once
Condition check Before loop Before loop After loop
body
Minimum runs 0 (can skip) 0 (can skip) Always 1
time
Counter setup Inside for() Outside loop Outside loop
Common use Arrays, fixed User input, files Menus, input
count validation
2.4 break and continue Statements
break — Exit the Loop Immediately
break immediately stops the loop and jumps to the code after the loop.
Java Code
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break; // Stop the loop when i reaches 5
}
[Link](i);
}
[Link]("Loop stopped!");
// Output: 1 2 3 4 Loop stopped! (stops before printing 5)
continue — Skip Current Iteration
continue skips the REST of the current iteration and jumps to the next one.
Java Code
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue; // Skip when i is 3 — go to next iteration
}
[Link](i);
}
// Output: 1 2 4 5 (3 is skipped!)
Statement What it does Where it jumps
break Immediately EXITS the loop Code after the loop
continue Skips rest of current iteration Next iteration of loop
TOPIC 3
TYPE CASTING IN JAVA
Type Casting means converting a variable from ONE data type to ANOTHER data type. Java is a
strongly-typed language — you cannot mix types freely, so casting is needed.
🔸 Real-Life Analogy: Type casting is like converting currency — ₹ to $ or $ to €. The
value changes in representation, but it still represents the same quantity (approximately).
Java Data Types from smallest to largest (in terms of memory):
Data Type Size Order (Widening Direction →)
byte → short → int → long → float → double
8bit 16bit 32bit 64bit 32bit 64bit
Moving LEFT to RIGHT = Widening (safe, no data loss)
Moving RIGHT to LEFT = Narrowing (risky, may lose data)
3.1 Widening (Implicit) Type Casting
Widening casting happens automatically when you convert a SMALLER data type to a LARGER one. No
data is lost. Java does this for you automatically.
• Also called: Implicit Casting / Automatic Casting / Upcasting
• Direction: byte → short → int → long → float → double
• Safe: No loss of data (larger type can hold all values of smaller type)
Java Code
class WideningDemo {
public static void main(String[] args) {
int num = 100; // int: 32-bit
long bigNum = num; // int → long (automatic, no cast
needed)
float fNum = num; // int → float (automatic)
double dNum = num; // int → double (automatic)
[Link]("int value: " + num); // 100
[Link]("long value: " + bigNum); // 100
[Link]("float value: " + fNum); // 100.0
[Link]("double value: " + dNum); // 100.0
// Another example: byte to int
byte b = 42;
int i = b; // byte → int automatically (widening)
[Link]("byte " + b + " as int: " + i);
}
}
✅ Key Rule: Widening is SAFE and AUTOMATIC. Java converts it without you asking.
Small type fits perfectly inside a larger type — like putting a small box inside a big box.
3.2 Narrowing (Explicit) Type Casting
Narrowing casting converts a LARGER data type to a SMALLER one. This can cause data loss
(truncation). YOU must explicitly tell Java to do this using a cast operator.
• Also called: Explicit Casting / Manual Casting / Downcasting
• Direction: double → float → long → int → short → byte
• Risky: Data may be lost (fractional part cut off, or value overflow)
Syntax of explicit cast:
smallerType variable = (smallerType) largerValue;
Example: int x = (int) 9.99; // x becomes 9 (decimal dropped!)
Java Code
class NarrowingDemo {
public static void main(String[] args) {
double d = 9.78; // double value with decimal
int i = (int) d; // Explicit cast: double → int
// The decimal part .78 is TRUNCATED (cut off), NOT rounded
[Link]("double value: " + d); // 9.78
[Link]("int value: " + i); // 9 (not 10!)
// ── Another example ──
long bigNum = 130L; // 130 as long
byte b = (byte) bigNum; // long → byte (byte holds -128 to 127)
[Link]("long value: " + bigNum); // 130
[Link]("byte value: " + b); // -126 (overflow!)
// 130 doesn't fit in byte, so data is LOST
}
}
⚠️Important: Narrowing TRUNCATES decimals — 9.99 becomes 9, NOT 10. It does NOT
round. Also, if the value overflows the smaller type's range, you get unexpected results!
3.3 Type Casting with char
A char in Java stores a Unicode number. You can cast between char and int to get interesting results.
Java Code
class CharCastDemo {
public static void main(String[] args) {
char c = 'A'; // 'A' is stored as Unicode 65
int n = c; // char → int (widening, automatic)
[Link]("char 'A' as int: " + n); // Output: 65
int code = 66;
char letter = (char) code; // int → char (narrowing, explicit)
[Link]("int 66 as char: " + letter); // Output: B
// Useful for printing alphabet
for (int i = 65; i <= 90; i++) {
[Link]((char) i + " "); // A B C ... Z
}
}
}
Type Widening (Auto) Narrowing (Manual) Risk
byte → int ✅ Automatic Not needed None
double → int ❌ Not auto ✅ (int) needed Loses decimal part
int → double ✅ Automatic Not needed None
long → byte ❌ Not auto ✅ (byte) needed Overflow possible
char → int ✅ Automatic Not needed None
int → char ❌ Not auto ✅ (char) needed Loss if value > 65535
TOPIC 4
CLASSES AND OBJECTS IN JAVA
Classes and Objects are the FOUNDATION of Object-Oriented Programming (OOP). Everything in Java
revolves around classes and objects.
🔸 Real-Life Analogy: A CLASS is like a blueprint of a house. An OBJECT is the actual
house built from that blueprint. You can build MANY houses from ONE blueprint —
similarly, you can create MANY objects from ONE class.
4.1 What is a Class?
A class is a template/blueprint that defines the properties (variables) and behaviors (methods) that
objects of that type will have.
• A class does NOT occupy memory by itself — it's just a design
• Defined using the 'class' keyword
• Contains: variables (data/state) and methods (actions/behavior)
Syntax of a Class:
class ClassName {
// Variables (also called fields or instance variables)
dataType variableName;
// Methods (behaviors)
returnType methodName() {
// code
}
}
Java Code
// Defining a Class called 'Student'
class Student {
// Variables — represent DATA about a student
String name; // Student's name
int rollNo; // Roll number
float marks; // Marks obtained
// Method — represents BEHAVIOR of a student
void displayInfo() {
[Link]("Name : " + name);
[Link]("Roll No: " + rollNo);
[Link]("Marks : " + marks);
}
void checkResult() {
if (marks >= 40) {
[Link](name + " : PASS");
} else {
[Link](name + " : FAIL");
}
}
}
Parts of a Class Explained
String name → Instance variable: every Student object gets its own 'name'
int rollNo → Instance variable: each object has its own roll number
void displayInfo()→ Method: defines what a Student object CAN DO
void checkResult()→ Another method: checks pass/fail
The class itself takes NO memory — it's just a blueprint!
4.2 What is an Object?
An object is an INSTANCE (real copy) of a class. When you create an object, memory is allocated for all
the variables of that class.
• Objects are created using the 'new' keyword
• Each object has its OWN copy of the variables
• Objects use '.' (dot operator) to access variables and methods
Syntax to create an object:
ClassName objectName = new ClassName();
ClassName → Type of object (like a data type)
objectName → Name you give to this object
new → Allocates memory on the Heap
ClassName() → Calls the constructor
Java Code
class StudentDemo {
public static void main(String[] args) {
// ── Creating OBJECT 1 ──
Student s1 = new Student(); // Memory is allocated for s1
// Assigning values to s1's variables using dot (.) operator
[Link] = "Rahul";
[Link] = 101;
[Link] = 75.5f;
// Calling s1's methods
[Link]();
[Link]();
[Link]("------");
// ── Creating OBJECT 2 ──
Student s2 = new Student(); // New separate memory for s2
[Link] = "Priya";
[Link] = 102;
[Link] = 38.0f;
[Link]();
[Link]();
// s1 and s2 are INDEPENDENT — changing s1 doesn't affect s2
}
}
✅ Output: Name: Rahul | Roll No: 101 | Marks: 75.5 | Rahul: PASS --- Name: Priya | Roll
No: 102 | Marks: 38.0 | Priya: FAIL
4.3 Memory Allocation for Objects
When an object is created, Java uses two areas of memory: Stack and Heap.
Memory Area What is Stored Managed By
Stack Memory Object REFERENCE (the variable name Java automatically
like s1, s2)
Heap Memory Actual OBJECT DATA (the variable Garbage Collector
values)
🔸 Real-Life Analogy: Stack = a label/address in your notebook. Heap = the actual house
at that address. The label (reference) tells you WHERE the house (object) is located.
Java Code
Student s1 = new Student(); // 's1' stored in Stack
// actual Student data stored in Heap
[Link] = "Rahul"; // Goes to Heap through s1 reference
// ── Reference sharing (IMPORTANT!) ──
Student s3 = s1; // s3 points to the SAME object as s1
[Link] = "Suresh"; // Changing via s3 ALSO changes s1's data!
[Link]([Link]); // Output: Suresh (not Rahul!)
// Both s1 and s3 point to the SAME Heap memory location
Memory Allocation Summary
new keyword → Allocates fresh memory on the Heap
Object reference → Stored in Stack, contains Heap address
Instance variables → Each object gets its OWN copy in Heap
null reference → If you write: Student s = null; — s points to nothing
Garbage Collection → Java automatically frees Heap memory when no references exist
4.4 The 'this' Keyword
'this' is a reference to the CURRENT object — the object on which the method was called. It is used to
avoid naming confusion between instance variables and parameters.
Java Code
class Car {
String brand;
int speed;
void setDetails(String brand, int speed) {
// 'brand' here refers to PARAMETER (local), not the variable!
[Link] = brand; // '[Link]' = instance variable
[Link] = speed; // '[Link]' = instance variable
// Without 'this', Java would confuse parameter with instance var
}
void display() {
[Link]("Brand: " + [Link] + ", Speed: " +
[Link]);
}
}
class CarTest {
public static void main(String[] args) {
Car c = new Car();
[Link]("Honda", 180);
[Link](); // Brand: Honda, Speed: 180
}
}
TOPIC 5
CONSTRUCTORS IN JAVA
A Constructor is a special method that is automatically called when an object is created using 'new'. Its
job is to initialize the object's variables.
🔸 Real-Life Analogy: A constructor is like setting up a new phone — when you first turn it
on (create object), it asks for your name, language, WiFi setup (initializing variables). It
runs automatically!
5.1 Rules of Constructors
1. The constructor name MUST be EXACTLY the same as the class name
2. A constructor has NO return type — not even void
3. It is called AUTOMATICALLY when an object is created with 'new'
4. A class can have MULTIPLE constructors (constructor overloading)
5. If you don't write any constructor, Java provides a default one automatically
Feature Constructor Normal Method
Name Same as class name Any valid name
Return type NONE (not even void) Must have return type
Called by Automatically by 'new' Manually by programmer
Purpose Initialize object variables Perform any action
Overloading Yes (multiple allowed) Yes
5.2 Default Constructor (No-Argument Constructor)
A default constructor has NO parameters. It sets default values for variables. If you don't write any
constructor, Java automatically creates this for you.
Java Code
class Laptop {
String brand;
int ram;
double price;
// ── Default Constructor (No parameters) ──
Laptop() { // Same name as class, no return type
brand = "Unknown"; // Initialize with default values
ram = 4;
price = 0.0;
[Link]("Laptop object created!");
}
void display() {
[Link]("Brand: " + brand);
[Link]("RAM : " + ram + " GB");
[Link]("Price: ₹" + price);
}
}
class LaptopTest {
public static void main(String[] args) {
Laptop L1 = new Laptop(); // Calls Laptop() constructor
AUTOMATICALLY
// Output: 'Laptop object created!' (from constructor)
[Link]();
// Brand: Unknown | RAM: 4 GB | Price: ₹0.0
}
}
What happened behind the scenes
new Laptop() → Java allocates memory on Heap for the object
Laptop() → Constructor is called automatically
brand = 'Unknown' → Variables get their initial values
Object is ready → Reference is stored in L1
Without constructor→ Java would auto-create one that sets all vars to 0/null
5.3 Parameterized Constructor
A parameterized constructor accepts arguments, allowing you to set custom values when creating the
object. This is much more useful in real programs.
Java Code
class Student {
String name;
int rollNo;
float marks;
// ── Parameterized Constructor ──
Student(String n, int r, float m) { // Takes 3 parameters
[Link] = n; // '[Link]' = instance var, 'n' = parameter
[Link] = r;
[Link] = m;
[Link]("Student created: " + [Link]);
}
void displayInfo() {
[Link]("Name : " + name);
[Link]("Roll : " + rollNo);
[Link]("Marks : " + marks);
}
}
class StudentTest {
public static void main(String[] args) {
// Each object gets its own values during creation
Student s1 = new Student("Rahul", 101, 85.5f);
Student s2 = new Student("Priya", 102, 92.0f);
Student s3 = new Student("Amit", 103, 37.5f);
[Link]();
[Link]("---");
[Link]();
}
}
✅ Advantage: With parameterized constructors, you set values at the moment of creation
— no need to assign each variable separately using dot operator after creation.
5.4 Constructor Overloading
A class can have MULTIPLE constructors — each with a different number or type of parameters. Java
decides which constructor to call based on the arguments you pass.
🔸 Real-Life Analogy: Like ordering a pizza — you can order with custom toppings
(parameterized), or just say 'give me the default pizza' (default). Both are valid orders from
the same shop (class).
Java Code
class BankAccount {
String holderName;
long accountNo;
double balance;
// ── Constructor 1: No arguments ──
BankAccount() {
holderName = "Unknown";
accountNo = 0L;
balance = 0.0;
[Link]("Empty account created");
}
// ── Constructor 2: Name and Account Number only ──
BankAccount(String name, long accNo) {
[Link] = name;
[Link] = accNo;
[Link] = 0.0; // Default balance
[Link]("Account created for " + name);
}
// ── Constructor 3: All three values ──
BankAccount(String name, long accNo, double initialBalance) {
[Link] = name;
[Link] = accNo;
[Link] = initialBalance;
[Link]("Account created for " + name + " with ₹" +
initialBalance);
}
void showDetails() {
[Link]("Holder : " + holderName);
[Link]("Acc No : " + accountNo);
[Link]("Balance: ₹" + balance);
}
}
class BankTest {
public static void main(String[] args) {
// Java picks the matching constructor based on arguments
BankAccount a1 = new BankAccount(); //
Constructor 1
BankAccount a2 = new BankAccount("Rahul", 123456789L); //
Constructor 2
BankAccount a3 = new BankAccount("Priya", 987654321L, 50000.0); //
Constructor 3
[Link]();
}
}
5.5 Copy Constructor
A copy constructor creates a new object as an exact copy of an existing object. It takes an object of the
SAME class as its parameter.
Java Code
class Rectangle {
int length;
int width;
// Normal parameterized constructor
Rectangle(int l, int w) {
[Link] = l;
[Link] = w;
}
// ── Copy Constructor ──
Rectangle(Rectangle r) { // Takes another Rectangle object
[Link] = [Link]; // Copy values from 'r'
[Link] = [Link];
[Link]("Copy created!");
}
int area() { return length * width; }
}
class RectTest {
public static void main(String[] args) {
Rectangle r1 = new Rectangle(10, 5); // Original object
Rectangle r2 = new Rectangle(r1); // Copy of r1
[Link]("r1 area: " + [Link]()); // 50
[Link]("r2 area: " + [Link]()); // 50 (same)
[Link] = 20; // Change r2 — does NOT affect r1!
[Link]("r1 area after: " + [Link]()); // Still 50
[Link]("r2 area after: " + [Link]()); // Now 100
}
}
Copy Constructor vs Reference Copy
Rectangle r2 = r1; → Reference copy: both point to SAME object
Rectangle r2 = new Rectangle(r1) → Copy constructor: creates NEW independent object
Changing r2 reference copy affects r1 too!
Changing r2 from copy constructor does NOT affect r1
5.6 Complete Revision Summary
TOPIC 1 — Decision Making
if → Runs code only when condition is TRUE
if-else → One block for TRUE, another for FALSE
if-else-if → Multiple conditions checked one by one (top to bottom)
switch → Matches variable against fixed values; needs break; has default
switch works with: int, char, String (NOT float/double)
TOPIC 2 — Looping
for loop → Use when count is KNOWN; for(init; condition; update)
while loop → Use when count is UNKNOWN; check BEFORE body; may run 0 times
do-while → Always runs body ONCE; checks condition AFTER body
break → Immediately EXIT the loop
continue → Skip current iteration, go to next
TOPIC 3 — Type Casting
Widening → Small type to Large type; AUTOMATIC; no data loss (int → double)
Narrowing → Large type to Small type; MANUAL with (type); may lose data (double → int)
Decimal truncation: (int) 9.99 = 9 (NOT 10 — it does not round!)
char to int / int to char casting is also common in exams
TOPIC 4 — Classes and Objects
Class → Blueprint/Template (no memory allocated, just design)
Object → Real instance created from class using 'new' (memory allocated)
Heap → Where object DATA is stored
Stack → Where object REFERENCE (variable name) is stored
Dot (.) → Operator used to access object's variables and methods
this → Refers to current object; used to distinguish instance var from parameter
TOPIC 5 — Constructors
Constructor rules: same name as class, NO return type, auto-called by new
Default Constructor → No parameters; sets default values
Parameterized → Takes parameters; sets custom values at creation time
Overloading → Multiple constructors with different parameter lists
Copy Constructor → Takes object of same class; creates independent copy
If no constructor written → Java provides a default one automatically
UNIT 3
Unit: Arrays and Strings
Arrays • Types of Arrays • String Class Methods • StringBuffer Methods
From Basics to Advanced | Every Method With Examples
Unit Overview
This unit covers two of the most essential and heavily used tools in Java — Arrays and Strings. Master
these and you will be able to solve almost any data-handling problem.
Topic What You Will Learn
1. Arrays — Introduction What an array is, why we use it, how memory works
2. Creating an Array Declaration, instantiation, initialisation — 3 ways
3. Types of Arrays 1D arrays, 2D arrays (matrix), jagged arrays, 3D arrays
4. Array Operations Traversal, searching, sorting, passing to methods
5. String Class Immutable strings, 20+ methods with examples
6. StringBuffer Class Mutable strings, all key methods with examples
7. String vs StringBuffer Differences, when to use each
8. Quick Revision Exam-ready summary, Q&A, cheatsheet
1. Introduction to Arrays
1.1 What Is an Array?
An array is a fixed-size, ordered collection of elements of the same data type, stored in contiguous
(adjacent) memory locations.
Real-Life Analogy:
• A row of numbered lockers in a school. Each locker has a number (index) and can hold one item.
• Locker 0, Locker 1, Locker 2 ... all the same size, all in a straight line.
• You access any locker directly by its number — no need to search from the start.
Why use arrays instead of separate variables?
Without Array (Bad) With Array (Good)
int mark1=85, mark2=90, int[] marks = {85, 90, 78, 92, 88};
mark3=78, mark4=92,
mark5=88;
Print each individually — for loop — 3 lines handles any size
5 lines of code
Cannot scale — 100 int[] marks = new int[100]; — done
students = 100 variables
1.2 Key Properties of Arrays
• Fixed size: Once created, the size cannot be changed.
• Zero-indexed: First element is at index 0, last is at index length-1.
• Same type: All elements must be the same data type (int, double, String, etc.).
• Object in Java: Arrays are objects and stored on the heap.
• Default values: int → 0, double → 0.0, boolean → false, String → null.
1.3 Array Memory Visualised
int[] marks = {85, 90, 78, 92, 88};
Index: [0] [1] [2] [3] [4]
Value: 85 90 78 92 88
↑ ↑
marks[0] marks[4]
[Link] → 5
First element → marks[0] → 85
Last element → marks[[Link] - 1] → marks[4] → 88
⚠ Always remember: last valid index = [Link] - 1. Accessing array[[Link]] throws
ArrayIndexOutOfBoundsException.
2. Creating an Array — 3 Ways
2.1 Way 1 — Declare → Allocate → Assign (3 separate steps)
// Step 1: Declaration — tells Java the type and name
int[] marks;
// Step 2: Instantiation — allocates memory for 5 integers
marks = new int[5];
// Step 3: Initialisation — assign values one by one
marks[0] = 85;
marks[1] = 90;
marks[2] = 78;
marks[3] = 92;
marks[4] = 88;
[Link](marks[2]); // Output: 78
2.2 Way 2 — Declare and Allocate Together
// Declare and allocate in one line
int[] marks = new int[5];
// All elements default to 0 at this point
// marks = [0, 0, 0, 0, 0]
// Assign values later
marks[0] = 85;
marks[1] = 90;
// ... etc.
2.3 Way 3 — Array Literal (Declare + Allocate + Initialise at once)
// Most compact way — values known at compile time
int[] marks = {85, 90, 78, 92, 88};
double[] prices = {10.5, 20.0, 15.75};
String[] names = {"Alice", "Bob", "Carol"};
boolean[] flags = {true, false, true, true};
// Java auto-calculates the size from the number of values
[Link]([Link]); // 5
[Link]([Link]); // 3
💡 Prefer the literal syntax ({}) when you already know the values. Use new int[n] when the values will be filled
in later (e.g. from user input).
2.4 Traversing an Array — Two Ways
int[] marks = {85, 90, 78, 92, 88};
// Way 1: Standard for loop (when you need the index)
[Link]("--- for loop ---");
for (int i = 0; i < [Link]; i++) {
[Link]("marks[" + i + "] = " + marks[i]);
}
// Way 2: Enhanced for-each loop (clean, no index needed)
[Link]("--- for-each ---");
for (int m : marks) {
[Link](m);
}
--- for loop ---
marks[0] = 85
marks[1] = 90
marks[2] = 78
marks[3] = 92
marks[4] = 88
--- for-each ---
85 90 78 92 88
2.5 Useful Array Operations
Finding Sum and Average
int[] marks = {85, 90, 78, 92, 88};
int sum = 0;
for (int m : marks) {
sum += m;
}
double avg = (double) sum / [Link];
[Link]("Sum = " + sum);
[Link]("Average = " + avg);
Sum = 433
Average = 86.6
Finding Maximum and Minimum
int[] nums = {34, 7, 89, 12, 56, 3, 100, 45};
int max = nums[0]; // assume first element is max
int min = nums[0]; // assume first element is min
for (int n : nums) {
if (n > max) max = n;
if (n < min) min = n;
}
[Link]("Maximum = " + max);
[Link]("Minimum = " + min);
Maximum = 100
Minimum = 3
Sorting with [Link]() and Searching
import [Link];
int[] nums = {64, 25, 12, 22, 11};
[Link]("Before: " + [Link](nums));
[Link](nums); // sorts in ascending order
[Link]("After : " + [Link](nums));
// Binary search (only works on SORTED array)
int idx = [Link](nums, 22);
[Link]("22 found at index: " + idx);
Before: [64, 25, 12, 22, 11]
After : [11, 12, 22, 25, 64]
22 found at index: 2
3. Types of Arrays
3.1 One-Dimensional Array (1D)
A single row of elements — the most basic and common type.
// 1D array — a single row
int[] roll = {101, 102, 103, 104, 105};
// Print all elements
for (int i = 0; i < [Link]; i++) {
[Link]("Roll No: " + roll[i]);
}
Roll No: 101
Roll No: 102
Roll No: 103
Roll No: 104
Roll No: 105
3.2 Two-Dimensional Array (2D / Matrix)
A 2D array is like a table — it has rows and columns.
// Visualise a 3x3 matrix:
// col0 col1 col2
// row 0 [ 1 2 3 ]
// row 1 [ 4 5 6 ]
// row 2 [ 7 8 9 ]
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Access: matrix[row][column]
[Link](matrix[0][0]); // 1 (row 0, col 0)
[Link](matrix[1][2]); // 6 (row 1, col 2)
[Link](matrix[2][1]); // 8 (row 2, col 1)
1
6
8
Traversing a 2D Array — Nested Loops
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Outer loop: rows
for (int row = 0; row < [Link]; row++) {
// Inner loop: columns in this row
for (int col = 0; col < matrix[row].length; col++) {
[Link](matrix[row][col] + "\t");
}
[Link](); // new line after each row
}
1 2 3
4 5 6
7 8 9
Full Example — Student Marks (3 students, 3 subjects)
class StudentMarks {
public static void main(String[] args) {
// rows = students, columns = subjects (Maths, Science, English)
int[][] marks = {
{85, 90, 78}, // Student 0: Aarav
{72, 68, 88}, // Student 1: Priya
{91, 95, 87} // Student 2: Rohan
};
String[] students = {"Aarav", "Priya", "Rohan"};
String[] subjects = {"Maths", "Science", "English"};
for (int i = 0; i < [Link]; i++) {
int total = 0;
[Link](students[i] + ": ");
for (int j = 0; j < marks[i].length; j++) {
[Link](subjects[j] + "=" + marks[i][j] + " ");
total += marks[i][j];
}
[Link]("| Total=" + total);
}
}
}
Aarav: Maths=85 Science=90 English=78 | Total=253
Priya: Maths=72 Science=68 English=88 | Total=228
Rohan: Maths=91 Science=95 English=87 | Total=273
3.3 Jagged Array (Irregular 2D)
A jagged array is a 2D array where each row can have a different number of columns.
// Each row has a different size
int[][] jagged = new int[3][]; // 3 rows, columns not yet defined
jagged[0] = new int[2]; // row 0 has 2 columns
jagged[1] = new int[4]; // row 1 has 4 columns
jagged[2] = new int[3]; // row 2 has 3 columns
// Assign values
jagged[0][0]=1; jagged[0][1]=2;
jagged[1][0]=3; jagged[1][1]=4; jagged[1][2]=5; jagged[1][3]=6;
jagged[2][0]=7; jagged[2][1]=8; jagged[2][2]=9;
// Print — use jagged[i].length for each row's column count
for (int i = 0; i < [Link]; i++) {
for (int j = 0; j < jagged[i].length; j++) {
[Link](jagged[i][j] + " ");
}
[Link]();
}
1 2
3 4 5 6
7 8 9
3.4 Three-Dimensional Array (3D)
A 3D array is like multiple 2D matrices stacked together — think of it as layers of tables.
// 3D array: [layer][row][column]
int[][][] cube = {
{{1, 2}, {3, 4}}, // Layer 0
{{5, 6}, {7, 8}} // Layer 1
};
// Access: cube[layer][row][col]
[Link](cube[0][0][0]); // 1
[Link](cube[0][1][1]); // 4
[Link](cube[1][0][1]); // 6
[Link](cube[1][1][0]); // 7
// Traverse with 3 nested loops
for (int l = 0; l < [Link]; l++) {
[Link]("Layer " + l + ":");
for (int r = 0; r < cube[l].length; r++) {
for (int c = 0; c < cube[l][r].length; c++) {
[Link](cube[l][r][c] + " ");
}
[Link]();
}
}
Layer 0:
1 2
3 4
Layer 1:
5 6
7 8
3.5 Passing Arrays to Methods
class ArrayMethods {
// Method that takes an array as parameter
static void printArray(int[] arr) {
[Link]("Array: ");
for (int x : arr) [Link](x + " ");
[Link]();
}
// Method that returns an array
static int[] doubleEach(int[] arr) {
int[] result = new int[[Link]];
for (int i = 0; i < [Link]; i++) {
result[i] = arr[i] * 2;
}
return result;
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5};
printArray(nums);
int[] doubled = doubleEach(nums);
printArray(doubled);
}
}
Array: 1 2 3 4 5
Array: 2 4 6 8 10
⚠ Arrays are passed by reference in Java. If you modify the array inside a method, the original array outside
also changes — be careful!
4. The String Class
4.1 What Is a String?
A String is a sequence of characters. In Java, String is a class (not a primitive), part of [Link] — so
it is automatically available without any import.
The most important property of String in Java:
🔑 Strings are IMMUTABLE. Once a String object is created, its content cannot be changed. Every operation
that 'modifies' a string actually creates a brand-new String object.
// Creating Strings
String s1 = "Hello"; // string literal (preferred)
String s2 = new String("Hello"); // using new keyword
String s3 = "Java" + " " + "Programming"; // concatenation
// Immutability demonstration
String s = "Hello";
s = s + " World"; // does NOT modify original — creates a new object
[Link](s); // Hello World
4.2 String Comparison — == vs .equals()
String a = "Hello";
String b = "Hello";
String c = new String("Hello");
// == compares REFERENCES (memory addresses)
[Link](a == b); // true (same literal pool object)
[Link](a == c); // false (c is a new object)
// .equals() compares CONTENT
[Link]([Link](b)); // true
[Link]([Link](c)); // true ← use this always
// Case-insensitive comparison
[Link]("hello".equalsIgnoreCase("HELLO")); // true
✖ ALWAYS use .equals() to compare String content. Never use == for strings — it compares memory
addresses, not the actual text.
4.3 String Methods — Complete Reference with Examples
Below is every important String method with a description and a working example.
length() — Get the Number of Characters
String s = "Hello World";
[Link]([Link]()); // 11
String empty = "";
[Link]([Link]()); // 0
// Useful: get last character
char last = [Link]([Link]() - 1);
[Link](last); // d
charAt(index) — Get Character at a Position
String s = "Java";
// J a v a
// index: 0 1 2 3
[Link]([Link](0)); // J
[Link]([Link](2)); // v
[Link]([Link](3)); // a
// Print all characters using charAt
for (int i = 0; i < [Link](); i++) {
[Link]([Link](i) + " ");
}
// Output: J a v a
indexOf() and lastIndexOf() — Find Position of a Character/Substring
String s = "banana";
// b a n a n a
// index: 0 1 2 3 4 5
[Link]([Link]('a')); // 1 (FIRST occurrence)
[Link]([Link]('a')); // 5 (LAST occurrence)
[Link]([Link]('a', 2)); // 3 (search from index 2)
[Link]([Link]("an")); // 1 (first "an")
[Link]([Link]("xyz")); // -1 (not found)
substring() — Extract Part of a String
String s = "Hello World";
// 0123456789...
// substring(startIndex) — from start to end
[Link]([Link](6)); // World
// substring(startIndex, endIndex) — endIndex is EXCLUSIVE
[Link]([Link](0, 5)); // Hello
[Link]([Link](6, 11)); // World
// Extract first name from full name
String fullName = "Priya Sharma";
int space = [Link](' ');
[Link]([Link](0, space)); // Priya
[Link]([Link](space + 1)); // Sharma
⚠ substring(start, end): start is INCLUSIVE, end is EXCLUSIVE. So substring(0,5) gives characters at index
0,1,2,3,4 — NOT 5.
toLowerCase() and toUpperCase()
String s = "Hello World";
[Link]([Link]()); // hello world
[Link]([Link]()); // HELLO WORLD
// Case-insensitive username check
String input = "ADMIN";
String stored = "admin";
if ([Link]().equals(stored)) {
[Link]("Login OK");
}
trim() — Remove Leading and Trailing Spaces
String s = " Hello Java ";
[Link]("[" + s + "]"); // [ Hello Java ]
[Link]("[" + [Link]() + "]"); // [Hello Java]
// trim() does NOT remove spaces in the middle
String s2 = " Hello World ";
[Link]([Link]()); // Hello World (middle spaces stay)
replace() — Replace Characters or Substrings
String s = "Java is fun and Java is powerful";
// Replace a character
[Link]([Link]('a', '@'));
// J@v@ is fun @nd J@v@ is powerful
// Replace a substring (ALL occurrences)
[Link]([Link]("Java", "Python"));
// Python is fun and Python is powerful
// replaceFirst — only the first occurrence
[Link]([Link]("Java", "Python"));
// Python is fun and Java is powerful
contains() — Check if Substring Exists
String s = "Java Programming is great";
[Link]([Link]("Java")); // true
[Link]([Link]("Python")); // false
[Link]([Link]("great")); // true
// Practical: validate email
String email = "user@[Link]";
if ([Link]("@") && [Link](".")) {
[Link]("Valid email format");
}
startsWith() and endsWith()
String file = "report_2024.pdf";
[Link]([Link]("report")); // true
[Link]([Link]("data")); // false
[Link]([Link](".pdf")); // true
[Link]([Link](".txt")); // false
// Check file type
if ([Link](".pdf")) {
[Link]("This is a PDF file.");
}
split() — Split String into Array
String sentence = "Java is a great language";
String[] words = [Link](" "); // split by space
[Link]("Words: " + [Link]); // 5
for (String w : words) {
[Link](w);
}
// Split CSV data by comma
String csv = "Alice,25,Engineer,Mumbai";
String[] fields = [Link](",");
[Link]("Name : " + fields[0]); // Alice
[Link]("Age : " + fields[1]); // 25
[Link]("Job : " + fields[2]); // Engineer
[Link]("City : " + fields[3]); // Mumbai
Words: 5
Java is a great language
Name : Alice
Age : 25
Job : Engineer
City : Mumbai
toCharArray() — Convert String to char Array
String s = "Hello";
char[] chars = [Link]();
[Link]([Link]); // 5
for (char c : chars) {
[Link](c + " ");
}
// Output: H e l l o
// Reverse a string using char array
for (int i = [Link] - 1; i >= 0; i--) {
[Link](chars[i]);
}
// Output: olleH
isEmpty() and isBlank()
String a = "";
String b = " ";
String c = "Hello";
[Link]([Link]()); // true (length == 0)
[Link]([Link]()); // false (has spaces, length > 0)
[Link]([Link]()); // false
[Link]([Link]()); // true (Java 11+, empty or only
whitespace)
[Link]([Link]()); // true (only spaces)
[Link]([Link]()); // false
compareTo() — Lexicographic Comparison
String s1 = "Apple";
String s2 = "Banana";
String s3 = "Apple";
[Link]([Link](s2)); // negative (A < B)
[Link]([Link](s1)); // positive (B > A)
[Link]([Link](s3)); // 0 (equal)
// Used for sorting strings alphabetically
// Negative = s1 comes BEFORE s2
// Zero = s1 equals s2
// Positive = s1 comes AFTER s2
concat() — Join Two Strings
String first = "Hello";
String second = " World";
String result = [Link](second);
[Link](result); // Hello World
// Same as: String result = first + second;
// The + operator is more commonly used
valueOf() — Convert Other Types to String
int num = 42;
double pi = 3.14;
boolean b = true;
char c = 'Z';
[Link]([Link](num)); // "42"
[Link]([Link](pi)); // "3.14"
[Link]([Link](b)); // "true"
[Link]([Link](c)); // "Z"
// Alternative: [Link](num) or "" + num
4.4 String Methods — Quick Reference Table
Method What It Does Example
length() Returns number of characters "Hello".length() → 5
charAt(i) Character at index i "Java".charAt(1) → 'a'
indexOf(x) First position of x (-1 if not "banana".indexOf('a') → 1
found)
lastIndexOf(x) Last position of x "banana".lastIndexOf('a') → 5
substring(s) From index s to end "Hello".substring(2) → "llo"
substring(s,e) From s (inclusive) to e "Hello".substring(1,4) → "ell"
(exclusive)
toLowerCase() All lowercase "JAVA".toLowerCase() → "java"
toUpperCase() All uppercase "java".toUpperCase() → "JAVA"
trim() Remove leading/trailing " hi ".trim() → "hi"
spaces
replace(old, new) Replace all occurrences "aaa".replace('a','b') → "bbb"
contains(s) Check if substring exists "Java".contains("av") → true
startsWith(s) Check start prefix "Hello".startsWith("He") → true
endsWith(s) Check end suffix "Hello".endsWith("lo") → true
equals(s) Content comparison (case- "Hi".equals("hi") → false
sensitive)
equalsIgnoreCase(s) Content comparison (ignore "Hi".equalsIgnoreCase("hi") → true
case)
compareTo(s) Lexicographic compare "A".compareTo("B") → negative
split(regex) Split into String array "a,b,c".split(",") → {"a","b","c"}
toCharArray() Convert to char[] "Hi".toCharArray() → {'H','i'}
concat(s) Append another string "He".concat("llo") → "Hello"
isEmpty() True if length is 0 "".isEmpty() → true
valueOf(x) Convert int/double/etc. to [Link](42) → "42"
String
replaceAll(regex, s) Replace using regex pattern "a1b2".replaceAll("[0-9]","x") → "axbx"
5. The StringBuffer Class
5.1 What Is StringBuffer?
StringBuffer is a mutable sequence of characters. Unlike String, a StringBuffer object can be modified
after creation — characters can be appended, inserted, deleted, or reversed.
🔑 String = immutable (cannot change). StringBuffer = mutable (can change in-place). StringBuilder = same as
StringBuffer but NOT thread-safe (faster for single threads).
Feature String StringBuffer StringBuilder
Mutable? No (immutable) Yes Yes
Thread-safe? Yes Yes (synchronized) No
Performance Slow for changes Medium Fast (single-thread)
Use when Value won't change Multi-threaded apps Single-threaded, lots of
changes
5.2 Creating a StringBuffer
// Empty StringBuffer (default capacity 16)
StringBuffer sb1 = new StringBuffer();
// StringBuffer with initial content
StringBuffer sb2 = new StringBuffer("Hello");
// StringBuffer with specified initial capacity
StringBuffer sb3 = new StringBuffer(50);
[Link](sb2); // Hello
[Link]([Link]()); // 5 (number of characters)
[Link]([Link]()); // 21 (5 + 16 default buffer)
5.3 StringBuffer Methods — Each With Example
append() — Add Content to the End
StringBuffer sb = new StringBuffer("Hello");
[Link](" World"); // append String
[Link]("!");
[Link](" Count: ");
[Link](42); // append int
[Link](" Pi: ");
[Link](3.14); // append double
[Link](sb);
// Output: Hello World! Count: 42 Pi: 3.14
// append() returns 'this' so you can CHAIN calls:
StringBuffer sb2 = new StringBuffer();
[Link]("Java").append(" is").append(" awesome");
[Link](sb2); // Java is awesome
Hello World! Count: 42 Pi: 3.14
Java is awesome
insert(index, value) — Insert at Any Position
StringBuffer sb = new StringBuffer("Hello World");
// 0123456789...
// Insert " Beautiful" at position 5
[Link](5, " Beautiful");
[Link](sb); // Hello Beautiful World
// Insert a number
StringBuffer sb2 = new StringBuffer("Java 2024");
[Link](5, "SE ");
[Link](sb2); // Java SE 2024
// Insert at beginning (index 0)
StringBuffer sb3 = new StringBuffer("World");
[Link](0, "Hello ");
[Link](sb3); // Hello World
Hello Beautiful World
Java SE 2024
Hello World
delete(start, end) — Remove a Portion
StringBuffer sb = new StringBuffer("Hello Beautiful World");
// 0 6 16
// delete(startIndex, endIndex) — endIndex is EXCLUSIVE
[Link](6, 16); // removes " Beautiful"
[Link](sb); // Hello World
// deleteCharAt(index) — remove one character
StringBuffer sb2 = new StringBuffer("Hello!");
[Link](5); // removes '!'
[Link](sb2); // Hello
Hello World
Hello
reverse() — Reverse the Entire Content
StringBuffer sb = new StringBuffer("Java");
[Link]();
[Link](sb); // avaJ
// Classic palindrome check using reverse()
String word = "madam";
StringBuffer check = new StringBuffer(word);
String reversed = [Link]().toString();
if ([Link](reversed)) {
[Link](word + " is a palindrome!");
} else {
[Link](word + " is NOT a palindrome.");
}
word = "hello";
check = new StringBuffer(word);
reversed = [Link]().toString();
[Link]([Link](reversed) ? word + " is palindrome" : word + "
is NOT");
avaJ
madam is a palindrome!
hello is NOT
replace(start, end, newString) — Replace a Portion
StringBuffer sb = new StringBuffer("Hello Java World");
// 0 6 11
// replace(start, end, newStr) — end is EXCLUSIVE
[Link](6, 10, "Python");
[Link](sb); // Hello Python World
// The replacement can be longer or shorter than what was removed
StringBuffer sb2 = new StringBuffer("I love cats");
[Link](7, 11, "dogs");
[Link](sb2); // I love dogs
Hello Python World
I love dogs
charAt() and setCharAt() — Get and Set a Character
StringBuffer sb = new StringBuffer("Hello");
// charAt — read a character (same as String)
[Link]([Link](1)); // e
// setCharAt — MODIFY a character (String cannot do this!)
[Link](0, 'J'); // change 'H' to 'J'
[Link](sb); // Jello
[Link](4, '!');
[Link](sb); // Jell!
e
Jello
Jell!
indexOf() and lastIndexOf() — Find Position
StringBuffer sb = new StringBuffer("banana split");
[Link]([Link]("an")); // 1
[Link]([Link]("an")); // 3
[Link]([Link]("xyz")); // -1 (not found)
length() and capacity()
StringBuffer sb = new StringBuffer("Hello");
[Link]([Link]()); // 5 (actual content length)
[Link]([Link]()); // 21 (5 chars + 16 default buffer)
// ensureCapacity — pre-allocate space for performance
[Link](100);
[Link]([Link]()); // at least 100
// setLength — trim or pad content
[Link](3); // keeps only first 3 chars
[Link](sb); // Hel
toString() — Convert StringBuffer to String
StringBuffer sb = new StringBuffer();
[Link]("Hello").append(" ").append("World");
// Convert to String when done building
String result = [Link]();
[Link](result); // Hello World
[Link]([Link]().getSimpleName()); // String
// You MUST call toString() to pass to String methods
[Link]([Link]()); // HELLO WORLD
5.4 Full Practical Example — Building a Sentence
class StringBufferDemo {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
// Build a sentence piece by piece
[Link]("My name is ");
[Link]("Alice");
[Link](". I am ");
[Link](22);
[Link](" years old.");
[Link]("Built : " + sb);
// Insert title at the beginning
[Link](0, "Intro: ");
[Link]("Insert : " + sb);
// Replace "Alice" with "Priya"
int start = [Link]("Alice");
int end = start + "Alice".length();
[Link](start, end, "Priya");
[Link]("Replace: " + sb);
// Delete "Intro: "
[Link](0, 7);
[Link]("Delete : " + sb);
// Reverse to check
StringBuffer copy = new StringBuffer([Link]());
[Link]();
[Link]("Reverse: " + copy);
}
}
Built : My name is Alice. I am 22 years old.
Insert : Intro: My name is Alice. I am 22 years old.
Replace: Intro: My name is Priya. I am 22 years old.
Delete : My name is Priya. I am 22 years old.
Reverse: .dlo sraey 22 ma I .ayrP si eman yM
5.5 StringBuffer Methods — Quick Reference Table
Method What It Does Example
append(x) Add x to the end (any type) [Link]("Hi") or [Link](42)
insert(i, x) Insert x at index i [Link](5, "World")
delete(s, e) Remove chars from s (incl.) to [Link](2, 5)
e (excl.)
deleteCharAt(i) Remove single character at [Link](3)
index i
replace(s, e, str) Replace chars from s to e with [Link](0, 4, "Java")
str
reverse() Reverse the entire content [Link]()
charAt(i) Get character at index i [Link](0)
setCharAt(i, c) Set character at index i [Link](0,'J')
indexOf(s) First index of substring s [Link]("an")
lastIndexOf(s) Last index of substring s [Link]("an")
length() Number of characters stored [Link]()
capacity() Current allocated buffer size [Link]()
ensureCapacity(min) Pre-allocate at least min [Link](100)
capacity
setLength(n) Truncate or pad content to [Link](5)
length n
toString() Convert StringBuffer to String [Link]()
substring(s) Extract from s to end [Link](3)
substring(s,e) Extract from s to e (exclusive) [Link](2,6)
6. String vs StringBuffer — Key Differences
Aspect String StringBuffer
Mutability Immutable — cannot be Mutable — can be changed in-place
changed after creation
Memory Creates a new object for every Modifies the same object
change
Performance Slow when concatenating in Fast — no new objects created
loops
Thread safety Yes — safe to share across Yes — synchronized methods
threads
Package [Link] (auto-imported) [Link] (auto-imported)
Storage String constant pool Heap memory
Use when Value is fixed or rarely Value changes frequently (e.g. building a
changed string in a loop)
Performance Demonstration
// String concatenation in a loop — creates 10,000 new objects!
String s = "";
long t1 = [Link]();
for (int i = 0; i < 10000; i++) {
s += "a"; // SLOW — new String created each time
}
[Link]("String time: " + ([Link]()-t1) + "
ms");
// StringBuffer in a loop — modifies same object
StringBuffer sb = new StringBuffer();
long t2 = [Link]();
for (int i = 0; i < 10000; i++) {
[Link]("a"); // FAST — same object modified
}
[Link]("StringBuffer time: " + ([Link]()-t2) +
" ms");
// StringBuffer is typically 100x faster for heavy string building
🔑 Rule: Use String when the value will not change. Use StringBuffer (or StringBuilder) when you are building a
string through many append/modify operations.
7. Quick Revision — Exam Ready
7.1 Arrays — 6 Must-Know Points
• Arrays store multiple values of the same type in contiguous memory.
• Declare: int[] arr; Create: arr = new int[5]; Literal: int[] arr = {1,2,3};
• Index starts at 0. Last valid index = [Link] - 1.
• Access with arr[i]. Use for loop or for-each to traverse.
• 2D array: int[][] matrix = new int[rows][cols]; Access: matrix[row][col].
• Jagged array: each row can have a different number of columns.
7.2 String — 5 Must-Know Points
• String is immutable — every modification creates a new String object.
• Use .equals() to compare content, never == (which compares references).
• Most used methods: length(), charAt(), substring(), indexOf(), replace(), split(), toLowerCase(),
toUpperCase(), trim().
• String is in [Link] — no import needed.
• [Link](x) converts int, double, boolean, char → String.
7.3 StringBuffer — 5 Must-Know Points
• StringBuffer is mutable — modifications happen on the same object.
• Key methods: append(), insert(), delete(), replace(), reverse(), setCharAt(), toString().
• append() supports method chaining: [Link]("a").append("b").append("c").
• Always call toString() at the end to get a String from StringBuffer.
• Use StringBuffer over String when concatenating many times (e.g. in a loop).
7.4 Common Exam Questions & Answers
Question Answer
What is the default value 0
of an int array element?
What exception does an ArrayIndexOutOfBoundsException
invalid array index throw?
Can arrays store mixed No — all elements must be of the same declared type
types?
What does [Link] The total number of elements in the array
return?
Why use .equals() not == == compares references (memory addresses). .equals() compares the
for Strings? actual character content.
What does substring(2,5) "llo" — characters at index 2, 3, 4 (5 is excluded)
return for "Hello"?
What is an immutable An object whose state cannot be changed after creation. String is
object? immutable.
What is StringBuffer's StringBuffer is mutable and faster for repeated modifications — it
advantage over String? modifies the same object instead of creating new ones.
Difference between delete(s,e) removes a range of characters. deleteCharAt(i) removes
delete() and exactly one character at index i.
deleteCharAt()?
What does reverse() do in It reverses all characters in the buffer in-place. 'Java' becomes 'avaJ'.
StringBuffer?
What is a jagged array? A 2D array where each row can have a different number of columns.
What is the difference length = actual number of characters stored. capacity = total buffer
between length and space allocated.
capacity?
8. One-Page Cheatsheet
Arrays
Concept Syntax
1D declaration int[] arr = new int[5];
1D literal int[] arr = {10, 20, 30};
Access element arr[i]
Array length [Link]
Last element arr[[Link] - 1]
for loop traverse for (int i=0; i<[Link]; i++) { arr[i] }
for-each traverse for (int x : arr) { x }
Sort array [Link](arr);
Print array [Link](arr)
2D declare int[][] m = new int[3][4];
2D literal int[][] m = {{1,2},{3,4}};
2D access m[row][col]
2D nested loop for(int i...) for(int j...) m[i][j]
Jagged array int[][] j = new int[3][]; j[0]=new int[2];
String
Method Returns
[Link]() int — character count
[Link](i) char at index i
[Link](x) int — first position, -1 if absent
[Link](s,e) String — chars from s to e-1
[Link]() / String — changed case
toUpperCase()
[Link]() String — no leading/trailing spaces
[Link](old,new) String — all occurrences replaced
[Link](sub) boolean
[Link](regex) String[] — split into parts
[Link](t) boolean — content comparison
[Link](t) int: <0 / 0 / >0
[Link]() char[] array
[Link](x) String from int/double/boolean/char
Method What It Does
[Link](x) Add x to end — chainable
[Link](i, x) Insert x at position i
[Link](s, e) Remove chars s (incl.) to e (excl.)
[Link](i) Remove single char at i
[Link](s, e, str) Replace range s..e with str
[Link]() Reverse all content
[Link](i, c) Change char at index i
[Link]() Count of stored characters
[Link]() Total buffer size
[Link]() Convert to String
UNIT 3
Unit: Arrays and Strings
Arrays • Types of Arrays • String Class Methods • StringBuffer Methods
From Basics to Advanced | Every Method With Examples
Unit Overview
This unit covers two of the most essential and heavily used tools in Java — Arrays and Strings. Master
these and you will be able to solve almost any data-handling problem.
Topic What You Will Learn
1. Arrays — Introduction What an array is, why we use it, how memory works
2. Creating an Array Declaration, instantiation, initialisation — 3 ways
3. Types of Arrays 1D arrays, 2D arrays (matrix), jagged arrays, 3D arrays
4. Array Operations Traversal, searching, sorting, passing to methods
5. String Class Immutable strings, 20+ methods with examples
6. StringBuffer Class Mutable strings, all key methods with examples
7. String vs StringBuffer Differences, when to use each
8. Quick Revision Exam-ready summary, Q&A, cheatsheet
1. Introduction to Arrays
1.1 What Is an Array?
An array is a fixed-size, ordered collection of elements of the same data type, stored in contiguous
(adjacent) memory locations.
Real-Life Analogy:
• A row of numbered lockers in a school. Each locker has a number (index) and can hold one item.
• Locker 0, Locker 1, Locker 2 ... all the same size, all in a straight line.
• You access any locker directly by its number — no need to search from the start.
Why use arrays instead of separate variables?
Without Array (Bad) With Array (Good)
int mark1=85, mark2=90, int[] marks = {85, 90, 78, 92, 88};
mark3=78, mark4=92,
mark5=88;
Print each individually — for loop — 3 lines handles any size
5 lines of code
Cannot scale — 100 int[] marks = new int[100]; — done
students = 100 variables
1.2 Key Properties of Arrays
• Fixed size: Once created, the size cannot be changed.
• Zero-indexed: First element is at index 0, last is at index length-1.
• Same type: All elements must be the same data type (int, double, String, etc.).
• Object in Java: Arrays are objects and stored on the heap.
• Default values: int → 0, double → 0.0, boolean → false, String → null.
1.3 Array Memory Visualised
int[] marks = {85, 90, 78, 92, 88};
Index: [0] [1] [2] [3] [4]
Value: 85 90 78 92 88
↑ ↑
marks[0] marks[4]
[Link] → 5
First element → marks[0] → 85
Last element → marks[[Link] - 1] → marks[4] → 88
⚠ Always remember: last valid index = [Link] - 1. Accessing array[[Link]] throws
ArrayIndexOutOfBoundsException.
2. Creating an Array — 3 Ways
2.1 Way 1 — Declare → Allocate → Assign (3 separate steps)
// Step 1: Declaration — tells Java the type and name
int[] marks;
// Step 2: Instantiation — allocates memory for 5 integers
marks = new int[5];
// Step 3: Initialisation — assign values one by one
marks[0] = 85;
marks[1] = 90;
marks[2] = 78;
marks[3] = 92;
marks[4] = 88;
[Link](marks[2]); // Output: 78
2.2 Way 2 — Declare and Allocate Together
// Declare and allocate in one line
int[] marks = new int[5];
// All elements default to 0 at this point
// marks = [0, 0, 0, 0, 0]
// Assign values later
marks[0] = 85;
marks[1] = 90;
// ... etc.
2.3 Way 3 — Array Literal (Declare + Allocate + Initialise at once)
// Most compact way — values known at compile time
int[] marks = {85, 90, 78, 92, 88};
double[] prices = {10.5, 20.0, 15.75};
String[] names = {"Alice", "Bob", "Carol"};
boolean[] flags = {true, false, true, true};
// Java auto-calculates the size from the number of values
[Link]([Link]); // 5
[Link]([Link]); // 3
💡 Prefer the literal syntax ({}) when you already know the values. Use new int[n] when the values will be filled
in later (e.g. from user input).
2.4 Traversing an Array — Two Ways
int[] marks = {85, 90, 78, 92, 88};
// Way 1: Standard for loop (when you need the index)
[Link]("--- for loop ---");
for (int i = 0; i < [Link]; i++) {
[Link]("marks[" + i + "] = " + marks[i]);
}
// Way 2: Enhanced for-each loop (clean, no index needed)
[Link]("--- for-each ---");
for (int m : marks) {
[Link](m);
}
--- for loop ---
marks[0] = 85
marks[1] = 90
marks[2] = 78
marks[3] = 92
marks[4] = 88
--- for-each ---
85 90 78 92 88
2.5 Useful Array Operations
Finding Sum and Average
int[] marks = {85, 90, 78, 92, 88};
int sum = 0;
for (int m : marks) {
sum += m;
}
double avg = (double) sum / [Link];
[Link]("Sum = " + sum);
[Link]("Average = " + avg);
Sum = 433
Average = 86.6
Finding Maximum and Minimum
int[] nums = {34, 7, 89, 12, 56, 3, 100, 45};
int max = nums[0]; // assume first element is max
int min = nums[0]; // assume first element is min
for (int n : nums) {
if (n > max) max = n;
if (n < min) min = n;
}
[Link]("Maximum = " + max);
[Link]("Minimum = " + min);
Maximum = 100
Minimum = 3
Sorting with [Link]() and Searching
import [Link];
int[] nums = {64, 25, 12, 22, 11};
[Link]("Before: " + [Link](nums));
[Link](nums); // sorts in ascending order
[Link]("After : " + [Link](nums));
// Binary search (only works on SORTED array)
int idx = [Link](nums, 22);
[Link]("22 found at index: " + idx);
Before: [64, 25, 12, 22, 11]
After : [11, 12, 22, 25, 64]
22 found at index: 2
3. Types of Arrays
3.1 One-Dimensional Array (1D)
A single row of elements — the most basic and common type.
// 1D array — a single row
int[] roll = {101, 102, 103, 104, 105};
// Print all elements
for (int i = 0; i < [Link]; i++) {
[Link]("Roll No: " + roll[i]);
}
Roll No: 101
Roll No: 102
Roll No: 103
Roll No: 104
Roll No: 105
3.2 Two-Dimensional Array (2D / Matrix)
A 2D array is like a table — it has rows and columns.
// Visualise a 3x3 matrix:
// col0 col1 col2
// row 0 [ 1 2 3 ]
// row 1 [ 4 5 6 ]
// row 2 [ 7 8 9 ]
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Access: matrix[row][column]
[Link](matrix[0][0]); // 1 (row 0, col 0)
[Link](matrix[1][2]); // 6 (row 1, col 2)
[Link](matrix[2][1]); // 8 (row 2, col 1)
1
6
8
Traversing a 2D Array — Nested Loops
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Outer loop: rows
for (int row = 0; row < [Link]; row++) {
// Inner loop: columns in this row
for (int col = 0; col < matrix[row].length; col++) {
[Link](matrix[row][col] + "\t");
}
[Link](); // new line after each row
}
1 2 3
4 5 6
7 8 9
Full Example — Student Marks (3 students, 3 subjects)
class StudentMarks {
public static void main(String[] args) {
// rows = students, columns = subjects (Maths, Science, English)
int[][] marks = {
{85, 90, 78}, // Student 0: Aarav
{72, 68, 88}, // Student 1: Priya
{91, 95, 87} // Student 2: Rohan
};
String[] students = {"Aarav", "Priya", "Rohan"};
String[] subjects = {"Maths", "Science", "English"};
for (int i = 0; i < [Link]; i++) {
int total = 0;
[Link](students[i] + ": ");
for (int j = 0; j < marks[i].length; j++) {
[Link](subjects[j] + "=" + marks[i][j] + " ");
total += marks[i][j];
}
[Link]("| Total=" + total);
}
}
}
Aarav: Maths=85 Science=90 English=78 | Total=253
Priya: Maths=72 Science=68 English=88 | Total=228
Rohan: Maths=91 Science=95 English=87 | Total=273
3.3 Jagged Array (Irregular 2D)
A jagged array is a 2D array where each row can have a different number of columns.
// Each row has a different size
int[][] jagged = new int[3][]; // 3 rows, columns not yet defined
jagged[0] = new int[2]; // row 0 has 2 columns
jagged[1] = new int[4]; // row 1 has 4 columns
jagged[2] = new int[3]; // row 2 has 3 columns
// Assign values
jagged[0][0]=1; jagged[0][1]=2;
jagged[1][0]=3; jagged[1][1]=4; jagged[1][2]=5; jagged[1][3]=6;
jagged[2][0]=7; jagged[2][1]=8; jagged[2][2]=9;
// Print — use jagged[i].length for each row's column count
for (int i = 0; i < [Link]; i++) {
for (int j = 0; j < jagged[i].length; j++) {
[Link](jagged[i][j] + " ");
}
[Link]();
}
1 2
3 4 5 6
7 8 9
3.4 Three-Dimensional Array (3D)
A 3D array is like multiple 2D matrices stacked together — think of it as layers of tables.
// 3D array: [layer][row][column]
int[][][] cube = {
{{1, 2}, {3, 4}}, // Layer 0
{{5, 6}, {7, 8}} // Layer 1
};
// Access: cube[layer][row][col]
[Link](cube[0][0][0]); // 1
[Link](cube[0][1][1]); // 4
[Link](cube[1][0][1]); // 6
[Link](cube[1][1][0]); // 7
// Traverse with 3 nested loops
for (int l = 0; l < [Link]; l++) {
[Link]("Layer " + l + ":");
for (int r = 0; r < cube[l].length; r++) {
for (int c = 0; c < cube[l][r].length; c++) {
[Link](cube[l][r][c] + " ");
}
[Link]();
}
}
Layer 0:
1 2
3 4
Layer 1:
5 6
7 8
3.5 Passing Arrays to Methods
class ArrayMethods {
// Method that takes an array as parameter
static void printArray(int[] arr) {
[Link]("Array: ");
for (int x : arr) [Link](x + " ");
[Link]();
}
// Method that returns an array
static int[] doubleEach(int[] arr) {
int[] result = new int[[Link]];
for (int i = 0; i < [Link]; i++) {
result[i] = arr[i] * 2;
}
return result;
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5};
printArray(nums);
int[] doubled = doubleEach(nums);
printArray(doubled);
}
}
Array: 1 2 3 4 5
Array: 2 4 6 8 10
⚠ Arrays are passed by reference in Java. If you modify the array inside a method, the original array outside
also changes — be careful!
4. The String Class
4.1 What Is a String?
A String is a sequence of characters. In Java, String is a class (not a primitive), part of [Link] — so
it is automatically available without any import.
The most important property of String in Java:
🔑 Strings are IMMUTABLE. Once a String object is created, its content cannot be changed. Every operation
that 'modifies' a string actually creates a brand-new String object.
// Creating Strings
String s1 = "Hello"; // string literal (preferred)
String s2 = new String("Hello"); // using new keyword
String s3 = "Java" + " " + "Programming"; // concatenation
// Immutability demonstration
String s = "Hello";
s = s + " World"; // does NOT modify original — creates a new object
[Link](s); // Hello World
4.2 String Comparison — == vs .equals()
String a = "Hello";
String b = "Hello";
String c = new String("Hello");
// == compares REFERENCES (memory addresses)
[Link](a == b); // true (same literal pool object)
[Link](a == c); // false (c is a new object)
// .equals() compares CONTENT
[Link]([Link](b)); // true
[Link]([Link](c)); // true ← use this always
// Case-insensitive comparison
[Link]("hello".equalsIgnoreCase("HELLO")); // true
✖ ALWAYS use .equals() to compare String content. Never use == for strings — it compares memory
addresses, not the actual text.
4.3 String Methods — Complete Reference with Examples
Below is every important String method with a description and a working example.
length() — Get the Number of Characters
String s = "Hello World";
[Link]([Link]()); // 11
String empty = "";
[Link]([Link]()); // 0
// Useful: get last character
char last = [Link]([Link]() - 1);
[Link](last); // d
charAt(index) — Get Character at a Position
String s = "Java";
// J a v a
// index: 0 1 2 3
[Link]([Link](0)); // J
[Link]([Link](2)); // v
[Link]([Link](3)); // a
// Print all characters using charAt
for (int i = 0; i < [Link](); i++) {
[Link]([Link](i) + " ");
}
// Output: J a v a
indexOf() and lastIndexOf() — Find Position of a Character/Substring
String s = "banana";
// b a n a n a
// index: 0 1 2 3 4 5
[Link]([Link]('a')); // 1 (FIRST occurrence)
[Link]([Link]('a')); // 5 (LAST occurrence)
[Link]([Link]('a', 2)); // 3 (search from index 2)
[Link]([Link]("an")); // 1 (first "an")
[Link]([Link]("xyz")); // -1 (not found)
substring() — Extract Part of a String
String s = "Hello World";
// 0123456789...
// substring(startIndex) — from start to end
[Link]([Link](6)); // World
// substring(startIndex, endIndex) — endIndex is EXCLUSIVE
[Link]([Link](0, 5)); // Hello
[Link]([Link](6, 11)); // World
// Extract first name from full name
String fullName = "Priya Sharma";
int space = [Link](' ');
[Link]([Link](0, space)); // Priya
[Link]([Link](space + 1)); // Sharma
⚠ substring(start, end): start is INCLUSIVE, end is EXCLUSIVE. So substring(0,5) gives characters at index
0,1,2,3,4 — NOT 5.
toLowerCase() and toUpperCase()
String s = "Hello World";
[Link]([Link]()); // hello world
[Link]([Link]()); // HELLO WORLD
// Case-insensitive username check
String input = "ADMIN";
String stored = "admin";
if ([Link]().equals(stored)) {
[Link]("Login OK");
}
trim() — Remove Leading and Trailing Spaces
String s = " Hello Java ";
[Link]("[" + s + "]"); // [ Hello Java ]
[Link]("[" + [Link]() + "]"); // [Hello Java]
// trim() does NOT remove spaces in the middle
String s2 = " Hello World ";
[Link]([Link]()); // Hello World (middle spaces stay)
replace() — Replace Characters or Substrings
String s = "Java is fun and Java is powerful";
// Replace a character
[Link]([Link]('a', '@'));
// J@v@ is fun @nd J@v@ is powerful
// Replace a substring (ALL occurrences)
[Link]([Link]("Java", "Python"));
// Python is fun and Python is powerful
// replaceFirst — only the first occurrence
[Link]([Link]("Java", "Python"));
// Python is fun and Java is powerful
contains() — Check if Substring Exists
String s = "Java Programming is great";
[Link]([Link]("Java")); // true
[Link]([Link]("Python")); // false
[Link]([Link]("great")); // true
// Practical: validate email
String email = "user@[Link]";
if ([Link]("@") && [Link](".")) {
[Link]("Valid email format");
}
startsWith() and endsWith()
String file = "report_2024.pdf";
[Link]([Link]("report")); // true
[Link]([Link]("data")); // false
[Link]([Link](".pdf")); // true
[Link]([Link](".txt")); // false
// Check file type
if ([Link](".pdf")) {
[Link]("This is a PDF file.");
}
split() — Split String into Array
String sentence = "Java is a great language";
String[] words = [Link](" "); // split by space
[Link]("Words: " + [Link]); // 5
for (String w : words) {
[Link](w);
}
// Split CSV data by comma
String csv = "Alice,25,Engineer,Mumbai";
String[] fields = [Link](",");
[Link]("Name : " + fields[0]); // Alice
[Link]("Age : " + fields[1]); // 25
[Link]("Job : " + fields[2]); // Engineer
[Link]("City : " + fields[3]); // Mumbai
Words: 5
Java is a great language
Name : Alice
Age : 25
Job : Engineer
City : Mumbai
toCharArray() — Convert String to char Array
String s = "Hello";
char[] chars = [Link]();
[Link]([Link]); // 5
for (char c : chars) {
[Link](c + " ");
}
// Output: H e l l o
// Reverse a string using char array
for (int i = [Link] - 1; i >= 0; i--) {
[Link](chars[i]);
}
// Output: olleH
isEmpty() and isBlank()
String a = "";
String b = " ";
String c = "Hello";
[Link]([Link]()); // true (length == 0)
[Link]([Link]()); // false (has spaces, length > 0)
[Link]([Link]()); // false
[Link]([Link]()); // true (Java 11+, empty or only
whitespace)
[Link]([Link]()); // true (only spaces)
[Link]([Link]()); // false
compareTo() — Lexicographic Comparison
String s1 = "Apple";
String s2 = "Banana";
String s3 = "Apple";
[Link]([Link](s2)); // negative (A < B)
[Link]([Link](s1)); // positive (B > A)
[Link]([Link](s3)); // 0 (equal)
// Used for sorting strings alphabetically
// Negative = s1 comes BEFORE s2
// Zero = s1 equals s2
// Positive = s1 comes AFTER s2
concat() — Join Two Strings
String first = "Hello";
String second = " World";
String result = [Link](second);
[Link](result); // Hello World
// Same as: String result = first + second;
// The + operator is more commonly used
valueOf() — Convert Other Types to String
int num = 42;
double pi = 3.14;
boolean b = true;
char c = 'Z';
[Link]([Link](num)); // "42"
[Link]([Link](pi)); // "3.14"
[Link]([Link](b)); // "true"
[Link]([Link](c)); // "Z"
// Alternative: [Link](num) or "" + num
4.4 String Methods — Quick Reference Table
Method What It Does Example
length() Returns number of characters "Hello".length() → 5
charAt(i) Character at index i "Java".charAt(1) → 'a'
indexOf(x) First position of x (-1 if not "banana".indexOf('a') → 1
found)
lastIndexOf(x) Last position of x "banana".lastIndexOf('a') → 5
substring(s) From index s to end "Hello".substring(2) → "llo"
substring(s,e) From s (inclusive) to e "Hello".substring(1,4) → "ell"
(exclusive)
toLowerCase() All lowercase "JAVA".toLowerCase() → "java"
toUpperCase() All uppercase "java".toUpperCase() → "JAVA"
trim() Remove leading/trailing " hi ".trim() → "hi"
spaces
replace(old, new) Replace all occurrences "aaa".replace('a','b') → "bbb"
contains(s) Check if substring exists "Java".contains("av") → true
startsWith(s) Check start prefix "Hello".startsWith("He") → true
endsWith(s) Check end suffix "Hello".endsWith("lo") → true
equals(s) Content comparison (case- "Hi".equals("hi") → false
sensitive)
equalsIgnoreCase(s) Content comparison (ignore "Hi".equalsIgnoreCase("hi") → true
case)
compareTo(s) Lexicographic compare "A".compareTo("B") → negative
split(regex) Split into String array "a,b,c".split(",") → {"a","b","c"}
toCharArray() Convert to char[] "Hi".toCharArray() → {'H','i'}
concat(s) Append another string "He".concat("llo") → "Hello"
isEmpty() True if length is 0 "".isEmpty() → true
valueOf(x) Convert int/double/etc. to [Link](42) → "42"
String
replaceAll(regex, s) Replace using regex pattern "a1b2".replaceAll("[0-9]","x") → "axbx"
5. The StringBuffer Class
5.1 What Is StringBuffer?
StringBuffer is a mutable sequence of characters. Unlike String, a StringBuffer object can be modified
after creation — characters can be appended, inserted, deleted, or reversed.
🔑 String = immutable (cannot change). StringBuffer = mutable (can change in-place). StringBuilder = same as
StringBuffer but NOT thread-safe (faster for single threads).
Feature String StringBuffer StringBuilder
Mutable? No (immutable) Yes Yes
Thread-safe? Yes Yes (synchronized) No
Performance Slow for changes Medium Fast (single-thread)
Use when Value won't change Multi-threaded apps Single-threaded, lots of
changes
5.2 Creating a StringBuffer
// Empty StringBuffer (default capacity 16)
StringBuffer sb1 = new StringBuffer();
// StringBuffer with initial content
StringBuffer sb2 = new StringBuffer("Hello");
// StringBuffer with specified initial capacity
StringBuffer sb3 = new StringBuffer(50);
[Link](sb2); // Hello
[Link]([Link]()); // 5 (number of characters)
[Link]([Link]()); // 21 (5 + 16 default buffer)
5.3 StringBuffer Methods — Each With Example
append() — Add Content to the End
StringBuffer sb = new StringBuffer("Hello");
[Link](" World"); // append String
[Link]("!");
[Link](" Count: ");
[Link](42); // append int
[Link](" Pi: ");
[Link](3.14); // append double
[Link](sb);
// Output: Hello World! Count: 42 Pi: 3.14
// append() returns 'this' so you can CHAIN calls:
StringBuffer sb2 = new StringBuffer();
[Link]("Java").append(" is").append(" awesome");
[Link](sb2); // Java is awesome
Hello World! Count: 42 Pi: 3.14
Java is awesome
insert(index, value) — Insert at Any Position
StringBuffer sb = new StringBuffer("Hello World");
// 0123456789...
// Insert " Beautiful" at position 5
[Link](5, " Beautiful");
[Link](sb); // Hello Beautiful World
// Insert a number
StringBuffer sb2 = new StringBuffer("Java 2024");
[Link](5, "SE ");
[Link](sb2); // Java SE 2024
// Insert at beginning (index 0)
StringBuffer sb3 = new StringBuffer("World");
[Link](0, "Hello ");
[Link](sb3); // Hello World
Hello Beautiful World
Java SE 2024
Hello World
delete(start, end) — Remove a Portion
StringBuffer sb = new StringBuffer("Hello Beautiful World");
// 0 6 16
// delete(startIndex, endIndex) — endIndex is EXCLUSIVE
[Link](6, 16); // removes " Beautiful"
[Link](sb); // Hello World
// deleteCharAt(index) — remove one character
StringBuffer sb2 = new StringBuffer("Hello!");
[Link](5); // removes '!'
[Link](sb2); // Hello
Hello World
Hello
reverse() — Reverse the Entire Content
StringBuffer sb = new StringBuffer("Java");
[Link]();
[Link](sb); // avaJ
// Classic palindrome check using reverse()
String word = "madam";
StringBuffer check = new StringBuffer(word);
String reversed = [Link]().toString();
if ([Link](reversed)) {
[Link](word + " is a palindrome!");
} else {
[Link](word + " is NOT a palindrome.");
}
word = "hello";
check = new StringBuffer(word);
reversed = [Link]().toString();
[Link]([Link](reversed) ? word + " is palindrome" : word + "
is NOT");
avaJ
madam is a palindrome!
hello is NOT
replace(start, end, newString) — Replace a Portion
StringBuffer sb = new StringBuffer("Hello Java World");
// 0 6 11
// replace(start, end, newStr) — end is EXCLUSIVE
[Link](6, 10, "Python");
[Link](sb); // Hello Python World
// The replacement can be longer or shorter than what was removed
StringBuffer sb2 = new StringBuffer("I love cats");
[Link](7, 11, "dogs");
[Link](sb2); // I love dogs
Hello Python World
I love dogs
charAt() and setCharAt() — Get and Set a Character
StringBuffer sb = new StringBuffer("Hello");
// charAt — read a character (same as String)
[Link]([Link](1)); // e
// setCharAt — MODIFY a character (String cannot do this!)
[Link](0, 'J'); // change 'H' to 'J'
[Link](sb); // Jello
[Link](4, '!');
[Link](sb); // Jell!
e
Jello
Jell!
indexOf() and lastIndexOf() — Find Position
StringBuffer sb = new StringBuffer("banana split");
[Link]([Link]("an")); // 1
[Link]([Link]("an")); // 3
[Link]([Link]("xyz")); // -1 (not found)
length() and capacity()
StringBuffer sb = new StringBuffer("Hello");
[Link]([Link]()); // 5 (actual content length)
[Link]([Link]()); // 21 (5 chars + 16 default buffer)
// ensureCapacity — pre-allocate space for performance
[Link](100);
[Link]([Link]()); // at least 100
// setLength — trim or pad content
[Link](3); // keeps only first 3 chars
[Link](sb); // Hel
toString() — Convert StringBuffer to String
StringBuffer sb = new StringBuffer();
[Link]("Hello").append(" ").append("World");
// Convert to String when done building
String result = [Link]();
[Link](result); // Hello World
[Link]([Link]().getSimpleName()); // String
// You MUST call toString() to pass to String methods
[Link]([Link]()); // HELLO WORLD
5.4 Full Practical Example — Building a Sentence
class StringBufferDemo {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
// Build a sentence piece by piece
[Link]("My name is ");
[Link]("Alice");
[Link](". I am ");
[Link](22);
[Link](" years old.");
[Link]("Built : " + sb);
// Insert title at the beginning
[Link](0, "Intro: ");
[Link]("Insert : " + sb);
// Replace "Alice" with "Priya"
int start = [Link]("Alice");
int end = start + "Alice".length();
[Link](start, end, "Priya");
[Link]("Replace: " + sb);
// Delete "Intro: "
[Link](0, 7);
[Link]("Delete : " + sb);
// Reverse to check
StringBuffer copy = new StringBuffer([Link]());
[Link]();
[Link]("Reverse: " + copy);
}
}
Built : My name is Alice. I am 22 years old.
Insert : Intro: My name is Alice. I am 22 years old.
Replace: Intro: My name is Priya. I am 22 years old.
Delete : My name is Priya. I am 22 years old.
Reverse: .dlo sraey 22 ma I .ayrP si eman yM
5.5 StringBuffer Methods — Quick Reference Table
Method What It Does Example
append(x) Add x to the end (any type) [Link]("Hi") or [Link](42)
insert(i, x) Insert x at index i [Link](5, "World")
delete(s, e) Remove chars from s (incl.) to [Link](2, 5)
e (excl.)
deleteCharAt(i) Remove single character at [Link](3)
index i
replace(s, e, str) Replace chars from s to e with [Link](0, 4, "Java")
str
reverse() Reverse the entire content [Link]()
charAt(i) Get character at index i [Link](0)
setCharAt(i, c) Set character at index i [Link](0,'J')
indexOf(s) First index of substring s [Link]("an")
lastIndexOf(s) Last index of substring s [Link]("an")
length() Number of characters stored [Link]()
capacity() Current allocated buffer size [Link]()
ensureCapacity(min) Pre-allocate at least min [Link](100)
capacity
setLength(n) Truncate or pad content to [Link](5)
length n
toString() Convert StringBuffer to String [Link]()
substring(s) Extract from s to end [Link](3)
substring(s,e) Extract from s to e (exclusive) [Link](2,6)
6. String vs StringBuffer — Key Differences
Aspect String StringBuffer
Mutability Immutable — cannot be Mutable — can be changed in-place
changed after creation
Memory Creates a new object for every Modifies the same object
change
Performance Slow when concatenating in Fast — no new objects created
loops
Thread safety Yes — safe to share across Yes — synchronized methods
threads
Package [Link] (auto-imported) [Link] (auto-imported)
Storage String constant pool Heap memory
Use when Value is fixed or rarely Value changes frequently (e.g. building a
changed string in a loop)
Performance Demonstration
// String concatenation in a loop — creates 10,000 new objects!
String s = "";
long t1 = [Link]();
for (int i = 0; i < 10000; i++) {
s += "a"; // SLOW — new String created each time
}
[Link]("String time: " + ([Link]()-t1) + "
ms");
// StringBuffer in a loop — modifies same object
StringBuffer sb = new StringBuffer();
long t2 = [Link]();
for (int i = 0; i < 10000; i++) {
[Link]("a"); // FAST — same object modified
}
[Link]("StringBuffer time: " + ([Link]()-t2) +
" ms");
// StringBuffer is typically 100x faster for heavy string building
🔑 Rule: Use String when the value will not change. Use StringBuffer (or StringBuilder) when you are building a
string through many append/modify operations.
7. Quick Revision — Exam Ready
7.1 Arrays — 6 Must-Know Points
• Arrays store multiple values of the same type in contiguous memory.
• Declare: int[] arr; Create: arr = new int[5]; Literal: int[] arr = {1,2,3};
• Index starts at 0. Last valid index = [Link] - 1.
• Access with arr[i]. Use for loop or for-each to traverse.
• 2D array: int[][] matrix = new int[rows][cols]; Access: matrix[row][col].
• Jagged array: each row can have a different number of columns.
7.2 String — 5 Must-Know Points
• String is immutable — every modification creates a new String object.
• Use .equals() to compare content, never == (which compares references).
• Most used methods: length(), charAt(), substring(), indexOf(), replace(), split(), toLowerCase(),
toUpperCase(), trim().
• String is in [Link] — no import needed.
• [Link](x) converts int, double, boolean, char → String.
7.3 StringBuffer — 5 Must-Know Points
• StringBuffer is mutable — modifications happen on the same object.
• Key methods: append(), insert(), delete(), replace(), reverse(), setCharAt(), toString().
• append() supports method chaining: [Link]("a").append("b").append("c").
• Always call toString() at the end to get a String from StringBuffer.
• Use StringBuffer over String when concatenating many times (e.g. in a loop).
7.4 Common Exam Questions & Answers
Question Answer
What is the default value 0
of an int array element?
What exception does an ArrayIndexOutOfBoundsException
invalid array index throw?
Can arrays store mixed No — all elements must be of the same declared type
types?
What does [Link] The total number of elements in the array
return?
Why use .equals() not == == compares references (memory addresses). .equals() compares the
for Strings? actual character content.
What does substring(2,5) "llo" — characters at index 2, 3, 4 (5 is excluded)
return for "Hello"?
What is an immutable An object whose state cannot be changed after creation. String is
object? immutable.
What is StringBuffer's StringBuffer is mutable and faster for repeated modifications — it
advantage over String? modifies the same object instead of creating new ones.
Difference between delete(s,e) removes a range of characters. deleteCharAt(i) removes
delete() and exactly one character at index i.
deleteCharAt()?
What does reverse() do in It reverses all characters in the buffer in-place. 'Java' becomes 'avaJ'.
StringBuffer?
What is a jagged array? A 2D array where each row can have a different number of columns.
What is the difference length = actual number of characters stored. capacity = total buffer
between length and space allocated.
capacity?
8. One-Page Cheatsheet
Arrays
Concept Syntax
1D declaration int[] arr = new int[5];
1D literal int[] arr = {10, 20, 30};
Access element arr[i]
Array length [Link]
Last element arr[[Link] - 1]
for loop traverse for (int i=0; i<[Link]; i++) { arr[i] }
for-each traverse for (int x : arr) { x }
Sort array [Link](arr);
Print array [Link](arr)
2D declare int[][] m = new int[3][4];
2D literal int[][] m = {{1,2},{3,4}};
2D access m[row][col]
2D nested loop for(int i...) for(int j...) m[i][j]
Jagged array int[][] j = new int[3][]; j[0]=new int[2];
String
Method Returns
[Link]() int — character count
[Link](i) char at index i
[Link](x) int — first position, -1 if absent
[Link](s,e) String — chars from s to e-1
[Link]() / String — changed case
toUpperCase()
[Link]() String — no leading/trailing spaces
[Link](old,new) String — all occurrences replaced
[Link](sub) boolean
[Link](regex) String[] — split into parts
[Link](t) boolean — content comparison
[Link](t) int: <0 / 0 / >0
[Link]() char[] array
[Link](x) String from int/double/boolean/char
StringBuffer
Method What It Does
[Link](x) Add x to end — chainable
[Link](i, x) Insert x at position i
[Link](s, e) Remove chars s (incl.) to e (excl.)
[Link](i) Remove single char at i
[Link](s, e, str) Replace range s..e with str
[Link]() Reverse all content
[Link](i, c) Change char at index i
[Link]() Count of stored characters
[Link]() Total buffer size
[Link]() Convert to String
Overview
This unit covers the heart of Object-Oriented Programming (OOP). Once you master these five topics,
you will write clean, reusable, and professional Java code.
Topic Core Idea
1. Inheritance A child class automatically gets all properties and methods of its
parent class
2. Polymorphism One interface, many forms — same method name behaves differently
in different classes
3. Method Overloading Same method name, different parameters — decided at compile time
4. Method Overriding Child class rewrites a parent method — decided at runtime
5. Nested & Inner Classes A class defined inside another class — for tight logical grouping
1. Inheritance
1.1 What Is Inheritance?
Inheritance is the mechanism by which one class acquires the properties (fields) and behaviours
(methods) of another class.
Real-Life Analogy:
• A child inherits their parent's eye colour, height, and some habits.
• In Java: a Child class inherits the fields and methods of a Parent class.
• The child can also add its own new fields/methods, and change (override) inherited behaviour.
💡 Why use inheritance? To reuse code. Instead of writing the same code in every class, write it once in the
parent and let all children share it automatically.
1.2 Terminology
Term Also Called Meaning
Parent class Super class / Base class The class whose code is being inherited
Child class Sub class / Derived class The class that inherits from the parent
extends — The keyword used to create inheritance
in Java
1.3 Syntax
class ParentClass {
// fields and methods
}
class ChildClass extends ParentClass {
// inherits everything from ParentClass
// can add new fields/methods here
// can override parent methods here
}
1.4 Simple Example — Animal and Dog
// Parent class
class Animal {
String name;
void eat() {
[Link](name + " is eating.");
}
void sleep() {
[Link](name + " is sleeping.");
}
}
// Child class — inherits eat() and sleep() from Animal
class Dog extends Animal {
// Dog's own method — not in Animal
void bark() {
[Link](name + " says: Woof!");
}
}
class Main {
public static void main(String[] args) {
Dog d = new Dog();
[Link] = "Bruno";
[Link](); // inherited from Animal
[Link](); // inherited from Animal
[Link](); // Dog's own method
}
}
Bruno is eating.
Bruno is sleeping.
Bruno says: Woof!
1.5 Types of Inheritance in Java
Type Description Supported in Java?
Single One child, one parent: A → B YES
Multilevel Chain: A → B → C YES
(Grandparent → Parent →
Child)
Hierarchical One parent, many children: A YES
→ B, A → C
Multiple One child, two parents: B + C NO (use Interface instead)
→A
Hybrid Mix of the above NO (use Interface instead)
Example — Single Inheritance
class Vehicle {
void start() { [Link]("Vehicle starting..."); }
}
class Car extends Vehicle { // Car IS-A Vehicle
void horn() { [Link]("Beep beep!"); }
}
// Car object can use both start() and horn()
Car c = new Car();
[Link](); // from Vehicle
[Link](); // from Car
Example — Multilevel Inheritance
class Animal {
void breathe() { [Link]("Breathing..."); }
}
class Mammal extends Animal { // Mammal IS-A Animal
void feedMilk() { [Link]("Feeding milk."); }
}
class Dog extends Mammal { // Dog IS-A Mammal IS-A Animal
void bark() { [Link]("Woof!"); }
}
Dog d = new Dog();
[Link](); // from Animal (grandparent)
[Link](); // from Mammal (parent)
[Link](); // Dog's own
Breathing...
Feeding milk.
Woof!
Example — Hierarchical Inheritance
class Shape {
void draw() { [Link]("Drawing a shape."); }
}
class Circle extends Shape { // Circle IS-A Shape
void area() { [Link]("Area = pi * r * r"); }
}
class Rectangle extends Shape { // Rectangle IS-A Shape
void area() { [Link]("Area = length * width"); }
}
Circle c = new Circle();
[Link](); // from Shape
[Link](); // Circle's own
Rectangle r = new Rectangle();
[Link](); // from Shape — same parent method
[Link](); // Rectangle's own
1.6 The super Keyword
The super keyword refers to the parent class. It is used in three ways:
Use Syntax What It Does
Call parent super() or super(args) Calls the parent class constructor —
constructor must be first line
Call parent method [Link]() Calls the parent's version of an
overridden method
Access parent field [Link] Accesses the parent's field when child
has same name
class Animal {
String name;
Animal(String name) {
[Link] = name;
[Link]("Animal constructor: " + name);
}
void describe() {
[Link]("I am an animal named " + name);
}
}
class Dog extends Animal {
String breed;
Dog(String name, String breed) {
super(name); // calls Animal(String name) constructor
[Link] = breed;
[Link]("Dog constructor: " + breed);
}
void describe() {
[Link](); // calls Animal's describe()
[Link]("Breed: " + breed);
}
}
Dog d = new Dog("Bruno", "Labrador");
[Link]();
Animal constructor: Bruno
Dog constructor: Labrador
I am an animal named Bruno
Breed: Labrador
⚠ super() must ALWAYS be the very first statement inside a child constructor. If you don't write it, Java adds
super() automatically.
1.7 Constructor Chaining in Inheritance
class A {
A() { [Link]("A constructor"); }
}
class B extends A {
B() { [Link]("B constructor"); }
}
class C extends B {
C() { [Link]("C constructor"); }
}
C obj = new C();
// Java calls: A() → B() → C() (top-down, parent first)
A constructor
B constructor
C constructor
🔑 Constructors always execute from the topmost parent DOWN to the child — even though you wrote new C(),
Java first runs A(), then B(), then C().
2. Polymorphism
2.1 What Is Polymorphism?
Polymorphism means "many forms". In Java, it means the same method name can behave differently
depending on the object or the arguments.
Real-Life Analogy:
• A person at work behaves as an "Employee".
• The same person at home behaves as a "Parent".
• The same person at cricket practice behaves as a "Player".
• One person — multiple forms of behaviour.
Type Also Called Resolved At How
Compile-time Static binding / Early Compile time Method Overloading
polymorphism binding
Runtime Dynamic binding / Runtime Method Overriding +
polymorphism Late binding Upcasting
2.2 Runtime Polymorphism — The Key Concept
Runtime polymorphism happens when a parent class reference holds a child class object. The method
called depends on the actual object at runtime, not the reference type.
class Animal {
void sound() { [Link]("Some generic sound"); }
}
class Dog extends Animal {
void sound() { [Link]("Woof!"); }
}
class Cat extends Animal {
void sound() { [Link]("Meow!"); }
}
class Parrot extends Animal {
void sound() { [Link]("Hello!"); }
}
class Main {
public static void main(String[] args) {
// Parent reference → Child object (UPCASTING)
Animal a1 = new Dog(); // a1 looks like Animal, IS a Dog
Animal a2 = new Cat();
Animal a3 = new Parrot();
[Link](); // calls Dog's sound() — decided at RUNTIME
[Link](); // calls Cat's sound() — decided at RUNTIME
[Link](); // calls Parrot's sound() — decided at RUNTIME
}
}
Woof!
Meow!
Hello!
💡 This is the power of polymorphism: you write Animal a = new Dog() and the right sound() is called
automatically. You can swap Dog for Cat without changing any other code.
2.3 Polymorphism with Arrays — Practical Power
// Store different animal objects in one Animal array
Animal[] zoo = { new Dog(), new Cat(), new Parrot(), new Dog() };
// One loop handles ALL types
for (Animal a : zoo) {
[Link](); // right method called for each actual type
}
Woof!
Meow!
Hello!
Woof!
2.4 Upcasting and Downcasting
Term Direction Automatic? Syntax
Upcasting Child → Parent YES — automatic Animal a = new Dog();
reference
Downcasting Parent reference → NO — must be explicit Dog d = (Dog) a;
Child type
Animal a = new Dog(); // upcasting — automatic
Dog d = (Dog) a; // downcasting — explicit cast needed
[Link](); // now you can call Dog-specific methods
// Safe downcasting with instanceof:
if (a instanceof Dog) {
Dog d2 = (Dog) a;
[Link]();
}
⚠ Always use instanceof before downcasting to avoid ClassCastException.
3. Method Overloading
3.1 What Is Method Overloading?
Method overloading means having multiple methods with the same name in the same class, but with
different parameters (different number, type, or order of parameters).
Real-Life Analogy:
• The word "open" is overloaded in English.
• "Open a door" vs "open a file" vs "open a bottle" — same word, different context.
🔑 Overloading = Same class, same name, DIFFERENT parameters. Resolved at COMPILE time.
3.2 Rules for Overloading
• Must change: number of parameters, OR type of parameters, OR order of parameters.
• NOT enough to change: only the return type.
• Overloaded methods can have different return types — but that alone is not enough.
• Access modifiers can be different.
Change Valid Overload? Example
Different number of YES add(int a) vs add(int a, int b)
parameters
Different type of YES add(int a, int b) vs add(double a,
parameters double b)
Different order of YES show(int, String) vs show(String, int)
types
Only return type NO — COMPILE ERROR int add(int a) vs double add(int a)
changed
3.3 Example 1 — Calculator with Overloaded add()
class Calculator {
// Version 1: two integers
int add(int a, int b) {
[Link]("int + int");
return a + b;
}
// Version 2: three integers
int add(int a, int b, int c) {
[Link]("int + int + int");
return a + b + c;
}
// Version 3: two doubles
double add(double a, double b) {
[Link]("double + double");
return a + b;
}
// Version 4: int and double
double add(int a, double b) {
[Link]("int + double");
return a + b;
}
}
class Main {
public static void main(String[] args) {
Calculator c = new Calculator();
[Link]([Link](5, 3)); // calls version 1
[Link]([Link](5, 3, 2)); // calls version 2
[Link]([Link](5.5, 3.2)); // calls version 3
[Link]([Link](5, 3.2)); // calls version 4
}
}
int + int
8
int + int + int
10
double + double
8.7
int + double
8.2
3.4 Example 2 — Overloaded print() Method
class Printer {
void print(String s) {
[Link]("String: " + s);
}
void print(int n) {
[Link]("Integer: " + n);
}
void print(double d) {
[Link]("Double: " + d);
}
void print(String s, int times) {
for (int i = 0; i < times; i++) [Link](s + " ");
[Link]();
}
}
Printer p = new Printer();
[Link]("Hello");
[Link](42);
[Link](3.14);
[Link]("Java", 3);
String: Hello
Integer: 42
Double: 3.14
Java Java Java
3.5 Example 3 — Overloaded area() — Different Shapes
class Geometry {
// Circle: one parameter
double area(double radius) {
return 3.14159 * radius * radius;
}
// Rectangle: two parameters
double area(double length, double width) {
return length * width;
}
// Triangle: two parameters but int type
double area(int base, int height) {
return 0.5 * base * height;
}
}
Geometry g = new Geometry();
[Link]("Circle area : " + [Link](7.0));
[Link]("Rectangle area: " + [Link](5.0, 3.0));
[Link]("Triangle area : " + [Link](6, 4));
Circle area : 153.93804...
Rectangle area: 15.0
Triangle area : 12.0
💡 Overloading makes your API intuitive. Users call the same method name and Java picks the right version
automatically based on what they pass.
4. Method Overriding
4.1 What Is Method Overriding?
Method overriding happens when a child class provides its own implementation for a method that is
already defined in the parent class.
Real-Life Analogy:
• Parent's recipe for making tea: milk + tea leaves + sugar.
• Child's version (override): same action (make tea) but adds cardamom and ginger.
• The recipe name is the same, the steps are different.
🔑 Overriding = Parent + Child, SAME method signature. Resolved at RUNTIME (that is why it enables runtime
polymorphism).
4.2 Rules for Overriding
• Method name must be exactly the same.
• Parameters must be exactly the same (same number, type, order).
• Return type must be same OR a subtype (covariant return type).
• Access modifier cannot be more restrictive — e.g. parent public → child CANNOT be
protected or private.
• Cannot override static, final, or private methods.
• Use @Override annotation — compiler checks you got the signature right.
4.3 Example 1 — Basic Override
class Animal {
void sound() {
[Link]("Animal makes a sound.");
}
}
class Dog extends Animal {
@Override // optional but strongly recommended
void sound() {
[Link]("Dog barks: Woof!");
}
}
class Cat extends Animal {
@Override
void sound() {
[Link]("Cat meows: Meow!");
}
}
Animal a = new Animal(); [Link](); // Animal's version
Animal d = new Dog(); [Link](); // Dog's version (runtime decision)
Animal c = new Cat(); [Link](); // Cat's version (runtime decision)
Animal makes a sound.
Dog barks: Woof!
Cat meows: Meow!
4.4 Example 2 — Overriding with super to Extend Behaviour
class Employee {
String name;
double salary;
Employee(String name, double salary) {
[Link] = name;
[Link] = salary;
}
void displayDetails() {
[Link]("Name : " + name);
[Link]("Salary : " + salary);
}
}
class Manager extends Employee {
int teamSize;
Manager(String name, double salary, int teamSize) {
super(name, salary);
[Link] = teamSize;
}
@Override
void displayDetails() {
[Link](); // reuse parent's output
[Link]("Team : " + teamSize + " members");
}
}
Manager m = new Manager("Priya", 95000, 8);
[Link]();
Name : Priya
Salary : 95000.0
Team : 8 members
4.5 Example 3 — Full Shapes System (Practical)
class Shape {
String color;
Shape(String color) { [Link] = color; }
double area() { return 0; } // default — will be overridden
void display() {
[Link]("Shape: " + getClass().getSimpleName() +
", Color: " + color +
", Area: " + area());
}
}
class Circle extends Shape {
double radius;
Circle(String color, double radius) {
super(color); [Link] = radius;
}
@Override
double area() { return 3.14159 * radius * radius; }
}
class Rectangle extends Shape {
double l, w;
Rectangle(String color, double l, double w) {
super(color); this.l = l; this.w = w;
}
@Override
double area() { return l * w; }
}
class Triangle extends Shape {
double base, height;
Triangle(String color, double base, double height) {
super(color); [Link] = base; [Link] = height;
}
@Override
double area() { return 0.5 * base * height; }
}
Shape[] shapes = {
new Circle("Red", 5),
new Rectangle("Blue", 4, 6),
new Triangle("Green", 3, 8)
};
for (Shape s : shapes) {
[Link](); // correct area() called for each shape
}
Shape: Circle, Color: Red, Area: 78.53975
Shape: Rectangle, Color: Blue, Area: 24.0
Shape: Triangle, Color: Green, Area: 12.0
4.6 Overloading vs Overriding — Full Comparison
Feature Overloading Overriding
Where? Same class Parent and child class
Method name Same Same
Parameters MUST be different MUST be same
Return type Can differ Must be same (or subtype)
Resolved at Compile time Runtime
Polymorphism type Compile-time (static) Runtime (dynamic)
@Override needed? No Recommended — yes
Access modifier Can be anything Cannot be more restrictive
Keyword No special keyword @Override annotation
5. Nested and Inner Classes
5.1 What Are Nested Classes?
A nested class is a class defined inside another class. The outer class is called the Outer class and
the class inside is the Nested class.
Why use nested classes?
• Logically group classes that are only used in one place.
• Increase encapsulation — the inner class can access outer class private members.
• Lead to more readable and maintainable code.
Type Keyword Can Access Outer? Use Case
Static Nested static Only static members Helper class not needing
Class outer instance
Non-static (none) All members including Tightly coupled helper
Inner Class private needing outer data
Local Inner (none — inside Local variables (if One-time use class inside
Class method) final/effectively final) a method
Anonymous (none — no name) Outer members Quick one-time
Inner Class implementation of
interface/abstract class
5.2 Non-static Inner Class
The most common type. Defined inside the outer class without static. It can access all fields and
methods of the outer class.
class Outer {
private int x = 100;
class Inner { // non-static inner class
void display() {
// Inner can access private member of Outer directly
[Link]("Outer x = " + x);
}
}
}
class Main {
public static void main(String[] args) {
Outer outer = new Outer(); // must create Outer first
[Link] inner = [Link] Inner(); // then create Inner
[Link]();
}
}
Outer x = 100
5.3 Static Nested Class
A static nested class is like a regular class but lives inside the outer class. It does NOT need an instance
of the outer class.
class Outer {
static int staticVar = 50;
int instanceVar = 99;
static class StaticNested {
void show() {
[Link]("staticVar = " + staticVar); // OK
// [Link](instanceVar); // ERROR — not static!
}
}
}
// No Outer instance needed — access directly
[Link] obj = new [Link]();
[Link]();
staticVar = 50
5.4 Local Inner Class
A local inner class is defined inside a method. It exists only within that method.
class Outer {
void outerMethod() {
int localVar = 42; // effectively final
class LocalInner { // class defined inside method
void display() {
[Link]("localVar = " + localVar);
}
}
LocalInner li = new LocalInner(); // create and use inside method
[Link]();
}
}
new Outer().outerMethod();
localVar = 42
5.5 Anonymous Inner Class
An anonymous inner class has no name. It is defined and instantiated in the same expression. It is
mainly used to implement an interface or extend a class for one-time use.
interface Greeting {
void sayHello();
}
class Main {
public static void main(String[] args) {
// Anonymous class: implements Greeting without creating a named
class
Greeting g = new Greeting() {
@Override
public void sayHello() {
[Link]("Hello from anonymous inner class!");
}
};
[Link]();
// Another anonymous class on the fly
Greeting g2 = new Greeting() {
@Override
public void sayHello() {
[Link]("Namaste from anonymous class 2!");
}
};
[Link]();
}
}
Hello from anonymous inner class!
Namaste from anonymous class 2!
5.6 Anonymous Class with Abstract Class
abstract class Animal {
abstract void sound();
void breathe() { [Link]("Breathing..."); }
}
class Main {
public static void main(String[] args) {
// Anonymous class extends abstract Animal
Animal lion = new Animal() {
@Override
void sound() {
[Link]("Lion roars: ROAR!");
}
};
[Link](); // calls anonymous class version
[Link](); // calls abstract class normal method
}
}
Lion roars: ROAR!
Breathing...
5.7 Practical Example — Engine inside Car
A real-world example: Car contains an Engine. Engine is a private implementation detail of Car, so it
makes sense to nest it inside Car.
class Car {
private String model;
private Engine engine; // outer class uses the inner class
Car(String model, int horsepower) {
[Link] = model;
[Link] = new Engine(horsepower);
}
void start() {
[Link](model + " starting...");
[Link]();
}
class Engine { // inner class — only Car needs to know Engine
details
int horsepower;
Engine(int hp) { [Link] = hp; }
void ignite() {
[Link]("Engine ignited! HP = " + horsepower);
[Link]("Model: " + model); // accesses outer's
private field
}
}
}
Car c = new Car("Tesla Model 3", 450);
[Link]();
Tesla Model 3 starting...
Engine ignited! HP = 450
Model: Tesla Model 3
6. Quick Revision — Exam Ready
6.1 Inheritance — 5 Must-Know Points
• Keyword: extends. Syntax: class Child extends Parent.
• Child inherits all public and protected members of Parent.
• super() calls parent constructor — must be first line in child constructor.
• [Link]() calls the parent's version of an overridden method.
• Constructors run top-down: grandparent → parent → child.
6.2 Polymorphism — 5 Must-Know Points
• Two types: Compile-time (overloading) and Runtime (overriding + upcasting).
• Upcasting: Animal a = new Dog() — automatic, no cast needed.
• Downcasting: Dog d = (Dog) a — explicit, use instanceof to be safe.
• Runtime polymorphism: correct overridden method is chosen at runtime based on actual object.
• Enables you to write one loop that works for all subtypes.
6.3 Overloading vs Overriding — Quick Recall
Question Overloading Overriding
Same class or parent- Same class Parent-child
child?
Parameters same or Different Same
different?
Resolved at compile Compile time Runtime
or runtime?
Polymorphism type? Static / Compile-time Dynamic / Runtime
6.4 Inner Classes — Quick Recall
Type Where Defined Key Point
Non-static Inner Inside outer class Needs outer instance. Can access all
outer members.
Static Nested Inside outer class (static) No outer instance needed. Only
accesses static outer members.
Local Inner Inside a method Scope limited to that method. Can
access final/effectively final local vars.
Anonymous Inline, no name One-time use. Implements interface or
extends class instantly.
6.5 Common Exam Questions & Answers
Question Answer
What is the difference Overloading: same class, different params, compile time. Overriding:
between overloading and parent-child, same params, runtime.
overriding?
Can we override a static No. Static methods belong to the class, not the object. They cannot be
method? overridden (can be hidden).
Can we override a private No. Private methods are not inherited so they cannot be overridden.
method?
Can we override a final No. final means it cannot be changed.
method?
What is @Override? An annotation that tells the compiler to verify you are correctly
overriding a parent method. Prevents accidental overloading.
What is upcasting? Assigning a child object to a parent reference: Animal a = new Dog();
What does super() do? Calls the parent class constructor. Must be the first line in the child
constructor.
Can inner class access Yes — non-static inner class can access all outer class members
outer private members? including private ones.
Difference: static nested Static nested does not need outer instance. Inner (non-static) needs
vs inner class? outer instance and can access instance members.
7. One-Page Cheatsheet
Concept Syntax / Key Rule
Single inheritance class Dog extends Animal { }
Multilevel inheritance class C extends B { } where class B extends A { }
Call parent constructor super(); or super(args); — first line of child constructor
Call parent method [Link]();
Upcasting Animal a = new Dog(); — automatic
Downcasting Dog d = (Dog) a; — explicit, check with instanceof first
Method overloading Same name, different parameters, same class
Method overriding @Override — same name + same params, parent-child, runtime
Cannot override static / private / final methods
Non-static inner class class Outer { class Inner { } } — needs outer instance
Static nested class class Outer { static class Nested { } } — no outer instance
Local inner class Define class inside a method — scope is that method only
Anonymous inner class new InterfaceName() { @Override void m() { } }
instanceof check if (a instanceof Dog) { Dog d = (Dog) a; }
@Override annotation Put on overriding method — compiler checks signature
UNIT 4
Unit Overview
This unit covers four core topics that every Java programmer must know. Here is a quick map of what we
will study:
Topic What You Will Learn
1. Modifiers & Access public, private, protected, default — who can see what
Control
2. Abstract Class Classes that act as templates and cannot be created directly
3. Interface A pure contract — what a class must do, not how
4. Packages Organising classes into folders / namespaces
1. Modifiers and Access Control
A modifier is a keyword placed before a class, variable, or method to control who can access it and
how it behaves.
Think of it like a building with different rooms — some rooms are open to everyone (public), some are
locked to outsiders (private), and some are available only to family members (protected).
1.1 Access Modifiers
Access modifiers control visibility — which other classes can read or change a field/method.
Modifier Who Can Access It? Real-Life Analogy
public Everyone, everywhere Front door of a shop — open to all
private Only inside the same class Your diary — only you can read it
protected Same package + any Family recipe — shared with relatives
subclass (child class)
(default / no keyword) Only inside the same Office memo — internal staff only
package
Example — All Four Together
Look at this single class and see all four modifiers at once:
class Test {
public int a = 10; // anyone can access a
private int b = 20; // only Test class can access b
protected int c = 30; // Test, same-package & subclasses
int d = 40; // default: same package only
}
Rule of thumb: Always use private for data fields and expose them via public getter/setter methods. This is
called Encapsulation.
How to Remember — Restrict to Open
Most restricted → Least restricted:
Order Modifier Openness
1 (tightest) private Only the class itself
2 (default) Same package
3 protected Package + subclasses
4 (most open) public The whole world
1.2 Non-Access Modifiers
These don't control visibility — they change behaviour.
Modifier Meaning
static Belongs to the class, not to any object
final Cannot be changed (constant variable / cannot be overridden)
abstract Has no body — must be completed by a subclass
synchronized Only one thread can run it at a time
💡 You will use static and final constantly. abstract is covered in depth in the next section.
2. Abstract Class
2.1 What Is an Abstract Class?
An abstract class is a half-built class — it provides some code (normal methods) but leaves some parts
intentionally blank (abstract methods) for child classes to fill in.
Key Idea: You cannot create an object (instance) directly from an abstract class. It is only used as a
parent/base class.
Real-Life Analogy:
• Abstract class = Vehicle. A vehicle is a concept — you cannot own a generic "vehicle".
• Subclass = Car, Bike, Truck. These are real, specific things you can own.
• The abstract method = move(). Every vehicle moves, but each one moves differently.
2.2 Syntax
abstract class ClassName {
// Abstract method — no body, only declaration
abstract void methodName();
// Normal (concrete) method — has a body
void normalMethod() {
[Link]("I have a body!");
}
}
2.3 Abstract Method
An abstract method has no body (no curly braces). It ends with a semicolon.
abstract void sound(); // declared but not defined
The child class that extends the abstract class MUST provide the body for every abstract method.
⚠ If a child class does not implement all abstract methods, the child class must also be declared abstract.
2.4 Complete Example — Step by Step
Step 1: Define the abstract class
abstract class Animal {
// Abstract method — every Animal makes a sound,
// but what sound depends on the animal type.
abstract void sound();
// Normal method — shared by ALL animals
void breathe() {
[Link]("Breathing...");
}
}
Step 2: Create a concrete (non-abstract) child class
class Dog extends Animal {
// MUST implement the abstract method from Animal
void sound() {
[Link]("Dog barks: Woof!");
}
}
class Cat extends Animal {
void sound() {
[Link]("Cat says: Meow!");
}
}
Step 3: Use the classes
class Main {
public static void main(String[] args) {
// Animal a = new Animal(); // ERROR! Cannot instantiate abstract
class
Dog d = new Dog();
[Link](); // Output: Dog barks: Woof!
[Link](); // Output: Breathing...
Cat c = new Cat();
[Link](); // Output: Cat says: Meow!
}
}
2.5 Key Rules — Quick Reference
Rule Explanation
Cannot instantiate new AbstractClass() always causes a compile error
Can have abstract methods Declared without body — child must complete it
Can have normal methods These are inherited directly by all children
Can have constructors Used internally when a child object is created
Can have variables Including static and final fields
Single inheritance only A class can extend only ONE abstract class
3. Interface
3.1 What Is an Interface?
An interface is a 100% abstract blueprint. It defines WHAT a class must do, but gives zero instructions
on HOW to do it.
Think of an interface as a contract. When a class signs the contract (implements the interface), it promises to
provide all the methods listed.
Real-Life Analogy:
• Interface = USB standard. The standard says "you must have a data pin, a power pin, etc.".
• A class = a USB flash drive. The flash drive follows the standard in its own way.
• Another class = a USB hard disk. Same standard, different implementation.
3.2 Syntax
interface InterfaceName {
// All methods are automatically: public + abstract
void method1();
int method2();
// All variables are automatically: public + static + final
int MAX = 100; // same as: public static final int MAX = 100;
}
3.3 Implementing an Interface
interface Animal {
void sound(); // public + abstract by default
}
class Dog implements Animal {
// Must be public — you cannot reduce visibility when implementing
public void sound() {
[Link]("Woof!");
}
}
⚠ When implementing an interface method, you MUST use the public keyword. Omitting it causes a compile
error because you'd be reducing its visibility.
3.4 Multiple Inheritance via Interface
The biggest advantage of an interface over an abstract class is that a class can implement multiple
interfaces at the same time.
interface Printable {
void print();
}
interface Scannable {
void scan();
}
// One class implements BOTH interfaces
class AllInOnePrinter implements Printable, Scannable {
public void print() {
[Link]("Printing document...");
}
public void scan() {
[Link]("Scanning document...");
}
}
class Main {
public static void main(String[] args) {
AllInOnePrinter machine = new AllInOnePrinter();
[Link]();
[Link]();
}
}
💡 Java does not allow a class to extend two classes (no multiple class inheritance) because of the "Diamond
Problem". Interfaces bypass this safely.
3.5 Interface Extends Interface
An interface can also extend another interface using the extends keyword:
interface A {
void methodA();
}
interface B extends A {
void methodB();
}
// A class implementing B must implement BOTH methodA() and methodB()
class MyClass implements B {
public void methodA() { [Link]("A"); }
public void methodB() { [Link]("B"); }
}
3.6 Abstract Class vs Interface — Full Comparison
Feature Abstract Class Interface
Methods Can have abstract + normal Only abstract methods (Java 7 and
methods below)
Variables Any type (int, String, etc.) public static final only (constants)
Constructor Can have a constructor Cannot have a constructor
Inheritance Single — extends one class Multiple — implements many interfaces
only
Keyword used extends implements
Speed Slightly faster Slightly slower (JVM extra lookup)
Use when... Classes share common Unrelated classes share a behaviour
code/state contract
💡 Quick decision: If you need shared code → use Abstract Class. If you only need a contract (what to do, not
how) → use Interface.
4. Packages in Java
4.1 What Is a Package?
A package is a folder/namespace that groups related classes together.
Why we need packages:
• Organise code — just like folders on your computer organise files.
• Avoid naming conflicts — two different packages can both have a class named "Date" without
clashing.
• Access control — packages work together with modifiers to control visibility.
• Reusability — import any package and use its classes in your project.
4.2 Types of Packages
Type Description Examples
Built-in (Java API) Provided by Java itself [Link], [Link], [Link], [Link]
User-defined Created by the programmer [Link], [Link]
Common built-in packages you will use often:
Package Contains
[Link] String, Math, System, Integer — auto-imported, always available
[Link] ArrayList, Scanner, HashMap, Date
[Link] File, InputStream, BufferedReader — for reading/writing files
[Link] BigInteger, BigDecimal — for very large numbers
4.3 Creating a User-Defined Package
The package statement must be the very first line in your .java file (before even import statements).
// File: mypack/[Link]
package mypack; // Line 1: declare the package
public class Hello {
public void greet() {
[Link]("Hello from mypack!");
}
}
4.4 Compiling and Running a Package — Step by Step
Step 1 — Compile and create the package folder
javac -d . [Link]
// -d . means: create the package folder in the current directory
// This creates: ./mypack/[Link]
Step 2 — Write another class that imports and uses the package
// File: [Link]
import [Link]; // import the specific class
// OR: import mypack.*; to import ALL classes from mypack
class Main {
public static void main(String[] args) {
Hello h = new Hello();
[Link](); // Output: Hello from mypack!
}
}
Step 3 — Compile and run Main
javac [Link]
java Main
// Output: Hello from mypack!
4.5 Package Naming Conventions
Java uses a standard naming convention for packages to ensure global uniqueness:
• All lowercase: [Link]
• Reverse domain name (for professional projects): [Link]
• Separate words with dots (each dot = a sub-folder): [Link]
For your college exercises, simple names like mypack or studentapp are perfectly fine.
4.6 Complete Working Example
// === File 1: mypack/[Link] ===
package mypack;
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int multiply(int a, int b) {
return a * b;
}
}
// === File 2: [Link] (in root, NOT in mypack) ===
import [Link];
class TestCalc {
public static void main(String[] args) {
Calculator c = new Calculator();
[Link]([Link](5, 3)); // Output: 8
[Link]([Link](4, 6)); // Output: 24
}
}
// Compile Calculator first, then TestCalc
javac -d . mypack/[Link]
javac [Link]
java TestCalc
5. Quick Revision — Exam Ready
5.1 Access Modifiers at a Glance
Modifier Same Class Same Package Subclass Everywhere
private YES NO NO NO
(default) YES YES NO NO
protected YES YES YES NO
public YES YES YES YES
5.2 Abstract Class — 5 Must-Know Points
• Declared with the abstract keyword before class.
• Cannot create an object: new AbstractClass() is a compile error.
• Can contain both abstract methods (no body) and normal methods (with body).
• Child class must implement all abstract methods, else child must also be abstract.
• Supports single inheritance only (extends one class).
5.3 Interface — 5 Must-Know Points
• All methods are public and abstract by default.
• All variables are public, static, and final (constants).
• A class uses the implements keyword to use an interface.
• One class can implement multiple interfaces (multiple inheritance).
• An interface cannot have a constructor.
5.4 Packages — 5 Must-Know Points
• package statement must be the very first line in a .java file.
• Compile with javac -d . [Link] to auto-create the folder.
• Use import to access classes from another package.
• Use import packagename.* to import all classes from a package.
• [Link] is automatically imported — you never need to write it yourself.
5.5 Common Exam Questions & Answers
Question Answer
Can we create an object of No. It causes a compile-time error.
an abstract class?
Can an abstract class have Yes. It runs when a child object is created.
a constructor?
Can an interface have a No. Interfaces cannot have constructors.
constructor?
What is the default access Package-private (same package only, no keyword).
level in Java?
Can a class implement two Yes. Separate them with commas: implements A, B.
interfaces?
What does -d . do in javac? Creates the package directory in the current folder.
Difference between extends extends is for classes/interfaces; implements is for interfaces only.
and implements?
6. One-Page Cheatsheet
Concept Syntax / Key Detail
public method public void show() { }
private variable private int age;
protected field protected String name;
Abstract class declaration abstract class Shape { }
Abstract method abstract void draw();
Extend abstract class class Circle extends Shape { }
Interface declaration interface Flyable { void fly(); }
Implement interface class Bird implements Flyable { }
Multiple interfaces class X implements A, B, C { }
Declare package package mypack; // Line 1 of file
Import one class import [Link];
Import all classes import mypack.*;
Compile with package javac -d . [Link]
static field static int count = 0; // shared by all objects
final constant final double PI = 3.14; // cannot change
Exception Handling
Unit: Exception Handling
Unit Overview
Before we dive in, here is the full picture of everything we will cover in this unit:
Topic What You Will Learn
1. What Is an Exception? The concept of runtime errors and why handling them matters
2. Exception Hierarchy How Java classifies all exceptions in a class tree
3. Exception Types Checked vs Unchecked vs Error — differences with examples
4. try-catch Catching a single exception and recovering gracefully
5. Multiple catch Handling different errors in one block of code
6. Nested try try blocks inside other try blocks — when and why
7. finally Code that ALWAYS runs, no matter what happens
8. throw Manually triggering an exception yourself
9. throws Declaring that a method might throw an exception
10. User-defined Creating your own custom exception classes
Exceptions
1. What Is an Exception?
An exception is an unexpected event that occurs during program execution (runtime) and disrupts
the normal flow of the program.
Think of it like driving a car:
• Normal flow = driving smoothly on the road.
• Exception = a flat tyre. Something unexpected happened mid-journey.
• Exception handling = you pull over, fix the tyre, and continue. The journey is not over.
Without exception handling, your program simply crashes and prints a scary error message. With
exception handling, you can catch the problem, show a friendly message, and keep the program running.
ℹ Exception handling does NOT prevent errors from happening. It lets you RESPOND to them gracefully
instead of crashing.
1.1 What Happens Without Exception Handling?
Here is a simple program that crashes at runtime:
class NoHandling {
public static void main(String[] args) {
int a = 10;
int b = 0;
int result = a / b; // ← PROBLEM: dividing by zero!
[Link](result);
[Link]("Program continues..."); // never reached
}
}
Output (program crashes):
Exception in thread "main" [Link]: / by zero
at [Link]([Link])
The program stopped at line 6. The last print statement never ran.
1.2 What Happens WITH Exception Handling?
class WithHandling {
public static void main(String[] args) {
int a = 10, b = 0;
try {
int result = a / b; // risky code here
} catch (ArithmeticException e) {
[Link]("Cannot divide by zero!");
}
[Link]("Program continues normally.");
}
}
Output (program runs fine):
Cannot divide by zero!
Program continues normally.
💡 Key Point: The program did not crash. We caught the exception, printed a friendly message, and continued.
2. The Exception Hierarchy
In Java, every exception is an object. All exception classes form a tree that looks like this:
[Link]
/ \
Exception Error
/ \ (JVM-level, cannot recover)
Checked RuntimeException
Exceptions (Unchecked Exceptions)
Examples: Examples:
IOException ArithmeticException
SQLException NullPointerException
FileNotFound ArrayIndexOutOfBounds
NumberFormatException
ClassCastException
Category Parent Class Must Handle? Examples
Checked Exception Yes — compiler IOException, SQLException,
Exception forces you FileNotFoundException
Unchecked RuntimeException No — optional to ArithmeticException,
Exception handle NullPointerException,
ArrayIndexOutOfBoundsException
Error Error No — do not try to OutOfMemoryError,
catch StackOverflowError
3. Exception Types — With Examples
3.1 Checked Exceptions
Checked exceptions are checked at compile time. The compiler refuses to build your program unless
you either handle them (try-catch) or declare them (throws).
Common checked exceptions:
Exception Class When It Occurs
IOException File or network operation fails
FileNotFoundException A file you tried to open does not exist
SQLException Database query fails
ClassNotFoundException A class is not found during dynamic loading
Example — Checked Exception
import [Link].*;
class CheckedDemo {
public static void main(String[] args) {
// Without try-catch, compiler gives ERROR:
// 'Unhandled exception type FileNotFoundException'
try {
FileReader f = new FileReader("[Link]");
[Link]("File opened!");
} catch (FileNotFoundException e) {
[Link]("File not found: " + [Link]());
}
}
}
⚠ Checked = the compiler checks it. You MUST handle it or the code will not compile.
3.2 Unchecked Exceptions (RuntimeException)
Unchecked exceptions occur at runtime and are usually caused by bugs in your logic. The compiler
does not force you to handle them, but you should.
Exception Class When It Occurs Common Cause
ArithmeticException Dividing by zero int x = 5/0;
NullPointerException Using a null reference String s = null; [Link]();
ArrayIndexOutOfBoundsException Accessing invalid int[] a = new int[3]; a[5] = 1;
index
NumberFormatException Parsing invalid [Link]("abc");
number string
ClassCastException Illegal type conversion Object o = "hi"; Integer i =
(Integer)o;
StringIndexOutOfBoundsExceptio Accessing invalid char "Hi".charAt(10);
n position
Example 1 — NullPointerException
class NPEDemo {
public static void main(String[] args) {
String name = null; // name has no value
try {
[Link]([Link]()); // crash! null has no methods
} catch (NullPointerException e) {
[Link]("Error: variable is null!");
}
}
}
// Output: Error: variable is null!
Example 2 — ArrayIndexOutOfBoundsException
class ArrayDemo {
public static void main(String[] args) {
int[] marks = {85, 90, 78}; // valid indices: 0, 1, 2
try {
[Link](marks[5]); // index 5 does not exist!
} catch (ArrayIndexOutOfBoundsException e) {
[Link]("Invalid index! Array has only 3 elements.");
}
}
}
Example 3 — NumberFormatException
class NumFormatDemo {
public static void main(String[] args) {
String input = "abc123"; // not a valid integer
try {
int num = [Link](input);
[Link]("Number: " + num);
} catch (NumberFormatException e) {
[Link]("Cannot convert '" + input + "' to a
number.");
}
}
}
// Output: Cannot convert 'abc123' to a number.
3.3 Errors
Errors are serious problems caused by the JVM itself, not your code. You should never try to catch
errors — they indicate the system is in an unrecoverable state.
Error Class When It Occurs
OutOfMemoryError JVM runs out of heap memory
StackOverflowError Infinite recursion fills the call stack
VirtualMachineError JVM is broken or has an internal issue
✖ Rule: Never write catch(Error e) or catch(Throwable t) in normal programs. Handle only Exception and its
subclasses.
4. try-catch Block
4.1 Syntax and How It Works
The try block contains the risky code. The catch block handles what to do if an exception occurs.
try {
// Risky code goes here
// If any line throws an exception,
// execution immediately jumps to catch
} catch (ExceptionType variableName) {
// What to do when that exception happens
// [Link]() gives the error description
}
Step-by-step execution flow:
• JVM enters the try block and runs the code line by line.
• If an exception occurs on any line, the rest of the try block is skipped.
• Execution jumps to the matching catch block.
• After catch finishes, the program continues normally below the try-catch.
• If NO exception occurs, the catch block is completely ignored.
4.2 Useful Methods on the Exception Object
Method What It Returns
[Link]() Short description of the error
[Link]() Class name + error message
[Link]() Full stack trace (file, line numbers) — useful for debugging
Example — All Three Methods
class ExceptionMethods {
public static void main(String[] args) {
try {
int[] arr = new int[3];
arr[10] = 99; // invalid index
} catch (ArrayIndexOutOfBoundsException e) {
[Link]("getMessage : " + [Link]());
[Link]("toString : " + [Link]());
[Link]("--- Stack Trace ---");
[Link]();
}
[Link]("Program continues after catch.");
}
}
getMessage : Index 10 out of bounds for length 3
toString : [Link]: Index 10 out of bounds
for length 3
--- Stack Trace ---
[Link]: Index 10 ...
at [Link]([Link])
Program continues after catch.
5. Multiple catch Blocks
One try block can have multiple catch blocks — one for each type of exception you want to handle
differently.
5.1 Syntax
try {
// risky code
} catch (ExceptionType1 e) {
// handle type 1
} catch (ExceptionType2 e) {
// handle type 2
} catch (ExceptionType3 e) {
// handle type 3
}
ℹ Only ONE catch block executes per exception. Java checks each catch from top to bottom and uses the first
one that matches.
5.2 Example — Multiple Catches with User Input
class MultipleCatch {
public static void main(String[] args) {
// Let's simulate different scenarios with an array and parsing
try {
int[] data = {10, 20, 30};
String input = "xyz"; // simulate bad input
int index = [Link](input); // throws
NumberFormatException
[Link](data[index]); // would throw
ArrayIndexOutOfBounds
int result = data[0] / 0; // would throw
ArithmeticException
} catch (NumberFormatException e) {
[Link]("Bad number format: " + [Link]());
} catch (ArrayIndexOutOfBoundsException e) {
[Link]("Index out of range: " + [Link]());
} catch (ArithmeticException e) {
[Link]("Math error: " + [Link]());
}
[Link]("Done.");
}
}
// Output: Bad number format: For input string: "xyz"
// Done.
5.3 Catch Order Rule — IMPORTANT
✖ Always catch child (specific) exceptions BEFORE parent (general) exceptions. Catching the parent first
makes all child catches unreachable — compiler error!
Wrong order (compiler error):
try {
// ...
} catch (Exception e) { // parent first — WRONG!
[Link]("General");
} catch (ArithmeticException e) { // child after — UNREACHABLE, compile error
[Link]("Math");
}
Correct order:
try {
// ...
} catch (ArithmeticException e) { // specific child first — CORRECT
[Link]("Math error");
} catch (Exception e) { // general parent last — catches everything
else
[Link]("Some other error");
}
5.4 Multi-Catch (Java 7+) — One Catch, Many Types
If you want to handle two exceptions the same way, you can combine them with a pipe | symbol:
try {
// risky code
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
// handles BOTH exceptions the same way
[Link]("Input or index error: " + [Link]());
}
💡 Multi-catch (pipe syntax) was introduced in Java 7. It keeps code clean when you want the same response
for different exceptions.
6. Nested try Block
A nested try is a try block inside another try block. This is used when different parts of your code can
fail independently and you want to handle each failure separately.
6.1 When to Use Nested try
• You have a multi-step operation where each step can fail differently.
• You want to continue with step 2 even if step 1 partially fails.
• Example: open a file (step 1) → parse its content (step 2) → do math on the data (step 3).
6.2 Syntax
try { // outer try
// step 1 — risky
try { // inner try
// step 2 — also risky
} catch (SomeException e) {
// handles step 2 error
}
// step 3 continues here
} catch (AnotherException e) {
// handles step 1 or step 3 error
}
6.3 Full Example — Nested try with Array and Division
class NestedTryDemo {
public static void main(String[] args) {
int[] arr = {10, 20, 0, 30};
try { // --- outer try ---
[Link]("Outer try: start");
[Link]("arr[5] = " + arr[5]); // will fail!
try { // --- inner try (only reached if outer succeeds) ---
[Link]("Inner try: start");
int result = arr[0] / arr[2]; // 10/0 = ArithmeticException
[Link]("Result: " + result);
} catch (ArithmeticException e) {
[Link]("Inner catch: " + [Link]());
}
} catch (ArrayIndexOutOfBoundsException e) {
[Link]("Outer catch: " + [Link]());
}
[Link]("After nested try.");
}
}
Output:
Outer try: start
Outer catch: Index 5 out of bounds for length 4
After nested try.
Now let us change arr[5] to arr[0] so the outer try succeeds and the inner try runs:
// Change: [Link](arr[0]) ← valid index
// New Output:
Outer try: start
10
Inner try: start
Inner catch: / by zero
After nested try.
⚠ Nested try is powerful but keep it at max 2 levels. Deeper nesting makes code very hard to read. Refactor
into separate methods instead.
7. finally Block
The finally block is code that ALWAYS executes — whether an exception occurred or not, whether it
was caught or not.
ℹ finally is used for CLEANUP CODE: closing files, closing database connections, releasing resources. You
never want to skip cleanup.
7.1 Syntax
try {
// risky code
} catch (ExceptionType e) {
// handle exception
} finally {
// THIS RUNS ALWAYS — exception or not
}
7.2 Three Scenarios — finally Always Runs
Scenario 1: No exception occurs
class FinallyDemo1 {
public static void main(String[] args) {
try {
[Link]("try: 10 / 2 = " + (10/2));
} catch (ArithmeticException e) {
[Link]("catch: " + [Link]());
} finally {
[Link]("finally: always runs");
}
}
}
try: 10 / 2 = 5
finally: always runs
// catch block was SKIPPED (no exception)
Scenario 2: Exception occurs AND is caught
class FinallyDemo2 {
public static void main(String[] args) {
try {
[Link]("try: 10 / 0");
int x = 10 / 0; // exception!
} catch (ArithmeticException e) {
[Link]("catch: " + [Link]());
} finally {
[Link]("finally: always runs");
}
}
}
try: 10 / 0
catch: / by zero
finally: always runs
// All three blocks ran
Scenario 3: Exception occurs but NOT caught
class FinallyDemo3 {
public static void main(String[] args) {
try {
[Link]("try: starting");
int x = 10 / 0;
} finally {
// No catch block! But finally still runs.
[Link]("finally: runs even without catch!");
}
// Program crashes after finally, but cleanup was done
}
}
try: starting
finally: runs even without catch!
Exception in thread "main" [Link]: / by zero
7.3 Practical Use Case — Closing a Resource
import [Link].*;
class ResourceCleanup {
public static void main(String[] args) {
FileReader file = null;
try {
file = new FileReader("[Link]");
// read data...
[Link]("Reading file...");
} catch (IOException e) {
[Link]("File error: " + [Link]());
} finally {
// Close the file WHETHER or NOT reading succeeded
try {
if (file != null) [Link]();
[Link]("File closed in finally.");
} catch (IOException e) {
[Link]("Could not close file.");
}
}
}
}
⚠ One edge case: finally does NOT run if [Link]() is called inside try/catch, or if the JVM itself crashes
(power failure, etc.).
8. throw — Manually Throwing an Exception
The throw keyword lets you manually create and throw an exception yourself, from inside your code.
Why would you want to throw an exception yourself?
• To enforce business rules. Example: age cannot be negative.
• To signal that input data is invalid.
• To stop a method and force the caller to handle a problem.
8.1 Syntax
throw new ExceptionClassName("Your error message here");
// Examples:
throw new ArithmeticException("Value cannot be zero");
throw new IllegalArgumentException("Age must be positive");
throw new NullPointerException("Name cannot be null");
ℹ throw always throws exactly ONE exception object. You must use new to create the exception object.
8.2 Example 1 — Validating Age
class ThrowDemo1 {
static void checkAge(int age) {
if (age < 0) {
// Manually throw an exception if age is invalid
throw new IllegalArgumentException("Age cannot be negative: " +
age);
}
[Link]("Valid age: " + age);
}
public static void main(String[] args) {
try {
checkAge(25); // valid
checkAge(-5); // invalid — will throw
} catch (IllegalArgumentException e) {
[Link]("Caught: " + [Link]());
}
}
}
// Output:
// Valid age: 25
// Caught: Age cannot be negative: -5
8.3 Example 2 — Bank Withdrawal Validation
class BankAccount {
private double balance;
BankAccount(double balance) {
[Link] = balance;
}
void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive.");
}
if (amount > balance) {
throw new ArithmeticException(
"Insufficient funds. Balance: " + balance);
}
balance -= amount;
[Link]("Withdrew " + amount + ". New balance: " +
balance);
}
public static void main(String[] args) {
BankAccount acc = new BankAccount(1000.0);
try {
[Link](300); // OK
[Link](800); // insufficient funds
} catch (ArithmeticException | IllegalArgumentException e) {
[Link]("Transaction failed: " + [Link]());
}
}
}
// Output:
// Withdrew 300.0. New balance: 700.0
// Transaction failed: Insufficient funds. Balance: 700.0
9. throws — Declaring Exceptions
The throws keyword is used in a method signature to declare that the method might throw a certain
exception — and the caller must handle it.
Keyword Used In Purpose
throw Inside method body Actually creates and throws an exception
object
throws Method signature Warns the caller: this method may throw
(declaration) this exception
9.1 Syntax
returnType methodName(parameters) throws ExceptionType1, ExceptionType2 {
// method body
}
9.2 Example 1 — Simple throws
class ThrowsDemo {
// This method declares that it MAY throw ArithmeticException
static int divide(int a, int b) throws ArithmeticException {
return a / b; // will throw if b is 0
}
public static void main(String[] args) {
try {
[Link](divide(10, 2)); // 5
[Link](divide(10, 0)); // exception!
} catch (ArithmeticException e) {
[Link]("Caught in main: " + [Link]());
}
}
}
// Output:
// 5
// Caught in main: / by zero
9.3 Example 2 — throws with Checked Exception (IOException)
import [Link].*;
class FileReader2 {
// Declares IOException — caller MUST handle it
static void readFile(String filename) throws IOException {
FileReader fr = new FileReader(filename);
[Link]("File opened: " + filename);
[Link]();
}
public static void main(String[] args) {
try {
readFile("[Link]");
} catch (IOException e) {
[Link]("File error: " + [Link]());
}
}
}
💡 throws is mainly useful for CHECKED exceptions. For unchecked exceptions you can use throws too, but it
is optional.
9.4 throw vs throws — Side by Side
Aspect throw throws
Used inside Method body Method signature
Throws One exception at a time Can declare multiple
Followed by An exception object (new ...) Exception class name(s)
Example throw new void read() throws IOException
IOException("oops");
Required for Both checked & unchecked Mainly checked exceptions
10. User-Defined (Custom) Exceptions
Java lets you create your own exception classes for domain-specific errors that the built-in exceptions
cannot clearly describe.
When do you need a custom exception?
• You want a meaningful exception name for your domain (e.g. InsufficientFundsException,
InvalidAgeException).
• You want to attach extra data to the exception (e.g. the invalid value itself).
• You are building a library or API for others to use.
10.1 How to Create a Custom Exception
• Extend Exception → creates a Checked custom exception (caller must handle it).
• Extend RuntimeException → creates an Unchecked custom exception (handling is optional).
// Checked custom exception
class MyException extends Exception {
MyException(String message) {
super(message); // pass message to Exception base class
}
}
// Unchecked custom exception
class MyRuntimeException extends RuntimeException {
MyRuntimeException(String message) {
super(message);
}
}
10.2 Example 1 — InvalidAgeException
// Step 1: Define the custom exception
class InvalidAgeException extends Exception {
private int age; // store the bad value for context
InvalidAgeException(int age) {
super("Invalid age: " + age + ". Age must be between 0 and 150.");
[Link] = age;
}
int getAge() { return age; }
}
// Step 2: Use it
class AgeValidator {
static void validateAge(int age) throws InvalidAgeException {
if (age < 0 || age > 150) {
throw new InvalidAgeException(age);
}
[Link]("Age " + age + " is valid.");
}
public static void main(String[] args) {
try {
validateAge(25); // valid
validateAge(-3); // invalid — throws our custom exception
validateAge(200); // never reached
} catch (InvalidAgeException e) {
[Link]("Caught: " + [Link]());
[Link]("Bad value was: " + [Link]());
}
}
}
// Output:
// Age 25 is valid.
// Caught: Invalid age: -3. Age must be between 0 and 150.
// Bad value was: -3
10.3 Example 2 — InsufficientFundsException (Bank System)
// Custom exception for banking
class InsufficientFundsException extends Exception {
private double shortage;
InsufficientFundsException(double shortage) {
super("Insufficient funds. You are short by: " + shortage);
[Link] = shortage;
}
double getShortage() { return shortage; }
}
class SavingsAccount {
private double balance;
SavingsAccount(double balance) { [Link] = balance; }
void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException(amount - balance);
}
balance -= amount;
[Link]("Withdrawn: " + amount + ". Remaining: " +
balance);
}
public static void main(String[] args) {
SavingsAccount acc = new SavingsAccount(500.0);
try {
[Link](200); // OK
[Link](400); // Fails — only 300 left
} catch (InsufficientFundsException e) {
[Link]([Link]());
[Link]("Please deposit at least: " +
[Link]());
}
}
}
// Output:
// Withdrawn: 200.0. Remaining: 300.0
// Insufficient funds. You are short by: 100.0
// Please deposit at least: 100.0
10.4 Example 3 — Full System with Multiple Custom Exceptions
// Custom exception 1
class UsernameException extends Exception {
UsernameException(String msg) { super(msg); }
}
// Custom exception 2
class PasswordException extends Exception {
PasswordException(String msg) { super(msg); }
}
class LoginSystem {
static void login(String user, String pass)
throws UsernameException, PasswordException {
if (user == null || [Link]() < 4) {
throw new UsernameException(
"Username too short (min 4 chars): '" + user + "'");
}
if (pass == null || [Link]() < 8) {
throw new PasswordException(
"Password too short (min 8 chars).");
}
[Link]("Login successful! Welcome, " + user);
}
public static void main(String[] args) {
String[][] tests = {
{"Al", "securePass"}, // bad username
{"Alice", "pass"}, // bad password
{"Alice", "securePass123"} // valid
};
for (String[] t : tests) {
try {
login(t[0], t[1]);
} catch (UsernameException e) {
[Link]("Username error: " + [Link]());
} catch (PasswordException e) {
[Link]("Password error: " + [Link]());
}
}
}
}
// Output:
// Username error: Username too short (min 4 chars): 'Al'
// Password error: Password too short (min 8 chars).
// Login successful! Welcome, Alice
11. Quick Revision — Exam Ready
11.1 Exception Types at a Glance
Type Extends Compiler checks? When to catch
Checked Exception YES — must handle FileNotFoundException,
SQLException,
IOException
Unchecked RuntimeException NO — optional NullPointer, ArrayIndex,
Arithmetic, NumberFormat
Error Error NO — never catch OutOfMemory,
StackOverflow
11.2 try-catch-finally Flow
try {
[risky code]
// If exception → jump to matching catch
// If no exception → skip all catch blocks
} catch (Type1 e) {
[handle Type1]
} catch (Type2 e) {
[handle Type2]
} finally {
[ALWAYS runs — exception or not]
}
[code here runs normally after try-catch-finally]
11.3 Keywords Summary
Keyword Role Used In
try Encloses risky code Block
catch Handles a specific exception Block after try
finally Cleanup — always runs Block after catch
throw Manually throw an exception Inside a method body
object
throws Declare that method may Method signature
throw
11.4 User-Defined Exception — 3-Step Recipe
• Step 1: Create class extending Exception or RuntimeException
• Step 2: Call super(message) in the constructor
• Step 3: throw it with throw new, catch it with catch
// Step 1
class MyException extends Exception {
MyException(String msg) { super(msg); } // Step 2
}
// Step 3
throw new MyException("something went wrong");
11.5 Common Exam Questions & Answers
Question Answer
What happens if no catch Exception propagates up the call stack. If main() also doesn't catch,
matches? JVM prints stack trace and terminates.
Can finally be skipped? Only if [Link]() is called or JVM crashes.
Can try exist without Yes — try { } finally { } is valid.
catch?
Difference between throw throw creates & throws an exception; throws declares a method may
and throws? throw.
Can one catch handle Yes — use pipe: catch(A | B e)
multiple exceptions?
Can a custom exception Yes — add fields, getters, and custom constructors.
have extra fields?
What is checked vs Checked: compiler forces handling. Unchecked: compiler doesn't
unchecked? check.
Order of multiple catch Child (specific) first, parent (general) last — else compile error.
blocks?
12. One-Page Cheatsheet
Concept Syntax
Basic try-catch try { } catch (Exception e) { }
Multiple catch } catch(A e) { } catch(B e) { }
Multi-catch (Java 7+) catch (A | B e) { }
finally try { } catch(E e){ } finally { }
try without catch try { } finally { }
Nested try try { try { } catch(B e){ } } catch(A e){ }
throw throw new ExceptionClass("message");
throws in method void foo() throws IOException { }
Custom checked class MyEx extends Exception { MyEx(String m){super(m);} }
Custom unchecked class MyEx extends RuntimeException { ... }
getMessage() [Link]() → short error string
printStackTrace() [Link]() → full stack trace to console
Catch order rule Specific (child) first, general (parent) last
Error (don't catch) OutOfMemoryError, StackOverflowError
UNIT V
FILE HANDLING IN JAVA
1. What is File Handling?
File handling means reading data from files and writing data into files using Java programs.
Why do we need File Handling?
Variables store data only while the program is running. When the program stops, all data in variables
is LOST.
Files store data permanently on the hard disk — even after the program ends.
Example: Think of saving a Word document. Even after closing Word, the file remains saved on your
computer.
Real-Life Analogy:
Think of RAM (variables) as a whiteboard — you can write on it, but wiping it clean erases everything. A
file is like a notebook — you can write once and come back to read it any time.
2. Understanding Streams in Java
A stream is a flow of data between your Java program and a file (or any source/destination).
Think of a stream like a water pipe: data flows through the pipe either INTO your program (reading) or
OUT of your program (writing).
There are TWO main types of streams:
(A) Byte Stream — For Binary Files
Byte streams work with raw binary data — that is, data in the form of bytes (0s and 1s).
• Works with 8-bit bytes
• Used for: images (.jpg, .png), videos (.mp4), audio (.mp3), compiled files (.class)
• NOT recommended for plain text files
Main Classes:
Class Purpose
FileInputStream Read binary data FROM a file
FileOutputStream Write binary data TO a file
Example — Reading a byte:
FileInputStream fin = new FileInputStream("[Link]");
int byteData = [Link](); // reads ONE byte at a time
[Link]();
// Explanation:
// [Link]() → Returns an integer (0–255) representing one byte
// Returns -1 → Means end of file reached
(B) Character Stream — For Text Files
Character streams work with text data using Unicode (supports all world languages).
• Works with 16-bit Unicode characters
• Used for: .txt files, .java files, .csv files, any readable text
• BEST for text files — handles special characters properly
Main Classes:
Class Purpose
FileReader Read text characters FROM a file
FileWriter Write text characters TO a file
Example — Reading a character:
FileReader fr = new FileReader("[Link]");
int charData = [Link](); // reads ONE character at a time
[Link]((char) charData); // cast int to char to display
[Link]();
// Explanation:
// [Link]() → Returns an integer (Unicode value) of the character
// (char) cast → Converts number back to actual character
// Returns -1 → End of file
Quick Comparison:
Feature Byte Stream Character Stream
Data Type Bytes (8-bit) Characters (16-bit Unicode)
Best For Images, Videos, Audio Text files
Read Class FileInputStream FileReader
Write Class FileOutputStream FileWriter
3. The File Class ([Link])
The File class represents a file or directory in your computer's file system. It does NOT read or write data
— it just gives you information about the file.
Package: [Link] (automatically available in most Java programs)
Creating a File Object:
File f = new File("[Link]");
// This does NOT create the file physically yet.
// It just creates a Java object that POINTS to '[Link]'
// Think of it like writing an address on paper —
// the address exists but the house may or may not exist.
Important Methods of File Class:
Method Returns What It Does
createNewFile() boolean Creates a new empty file.
Returns true if successful.
exists() boolean Checks if the file actually
exists on disk.
delete() boolean Deletes the file. Returns true if
deleted.
getName() String Returns just the file name
(e.g., '[Link]').
getPath() String Returns the full path (e.g.,
'C:/folder/[Link]').
length() long Returns the file size in bytes.
isFile() boolean Returns true if it's a file (not a
folder).
isDirectory() boolean Returns true if it's a folder.
mkdir() boolean Creates a new directory/folder.
4. Creating a File — Step by Step
To create a new file, we use the File class with the createNewFile() method.
Full Example with Explanation:
import [Link]; // Import File class
import [Link]; // Import for handling errors
class CreateFile {
public static void main(String[] args) throws IOException {
File f = new File("[Link]"); // Step 1: Create File object
if ([Link]()) { // Step 2: Try to create the file
[Link]("File created: " + [Link]());
} else {
[Link]("File already exists!");
}
}
}
Line-by-Line Explanation:
import [Link] → Brings in the File class so we can use it
import [Link] → File operations can fail, so we need this
new File("[Link]") → Creates an object representing [Link]
createNewFile() → Actually creates the file on your hard disk
Returns true → File was newly created
Returns false → File already existed
[Link]() → Prints just the filename ([Link])
Output: File created: [Link] (if file did not exist before)
5. Writing to a File — Step by Step
To write text into a file, we use the FileWriter class.
import [Link]; // Import FileWriter class
import [Link];
class WriteFile {
public static void main(String[] args) throws IOException {
// Step 1: Open/Create the file for writing
FileWriter fw = new FileWriter("[Link]");
// Step 2: Write data into the file
[Link]("Hello Students! Welcome to Java.");
// Step 3: MUST close the file to save data
[Link]();
[Link]("Data written successfully!");
}
}
Important Points:
new FileWriter("[Link]") → Opens file for writing. Creates it if it doesn't exist.
[Link]("...") → Writes the given text into the file.
[Link]() → VERY IMPORTANT — without this, data may not be saved!
WARNING: FileWriter OVERWRITES the file by default. Old data will be lost.
How to APPEND (add) data without deleting old content:
// Pass 'true' as second argument to enable append mode
FileWriter fw = new FileWriter("[Link]", true);
[Link]("This line is added at the end.");
[Link]();
// Without 'true' → File is overwritten (old data deleted)
// With 'true' → New data is added AFTER old data
6. Reading from a File — Step by Step
To read text from a file, we use the FileReader class.
import [Link];
import [Link];
class ReadFile {
public static void main(String[] args) throws IOException {
// Step 1: Open the file for reading
FileReader fr = new FileReader("[Link]");
int i; // Variable to hold each character's Unicode value
// Step 2: Read character by character until end of file
while ((i = [Link]()) != -1) {
[Link]((char) i); // Convert number to character
}
// Step 3: Close the file
[Link]();
}
}
Line-by-Line Explanation:
new FileReader("[Link]") → Opens the file for reading
[Link]() → Reads ONE character, returns its Unicode number (int)
(i = [Link]()) != -1 → Keeps reading until -1 is returned (end of file)
(char) i → Casts the integer back to a readable character
[Link]() → Always close after reading
Example: If file contains 'Hi' → read() returns 72 (H), then 105 (i), then -1
7. Deleting a File
import [Link];
class DeleteFile {
public static void main(String[] args) {
File f = new File("[Link]");
if ([Link]()) {
[Link]("File deleted: " + [Link]());
} else {
[Link]("File not found or cannot be deleted.");
}
}
}
Note: delete() returns true if file was found and deleted. Returns false if file does not exist.
8. File Operations Summary Table
Operation Class Used Key Method
Create File File createNewFile()
Write to File FileWriter write("text")
Append to File FileWriter (append mode) new FileWriter(file, true)
Read from File FileReader read()
Delete File File delete()
Check if Exists File exists()
Get File Size File length()
9. Buffered Streams — Faster File I/O
Normal file reading (FileReader) reads ONE character at a time — this is slow for large files.
Buffered streams read a big CHUNK of data at once into memory (buffer), then serve it — much faster!
Analogy: Normal reading = going to a shop one item at a time. Buffered = getting a whole shopping cart
of items at once.
BufferedReader — Fast Text Reading
import [Link];
import [Link];
import [Link];
class BufferedReadExample {
public static void main(String[] args) throws IOException {
// Wrap FileReader inside BufferedReader for speed
BufferedReader br = new BufferedReader(new FileReader("[Link]"));
String line;
// readLine() reads ONE full line at a time (much faster!)
while ((line = [Link]()) != null) {
[Link](line);
}
[Link]();
}
}
Key Differences from FileReader:
readLine() → Reads an entire line at once (FileReader reads char by char)
Returns null when end of file (instead of -1)
Much faster for reading large text files
BufferedReader wraps around FileReader — it enhances it!
BufferedWriter — Fast Text Writing
import [Link];
import [Link];
import [Link];
class BufferedWriteExample {
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("[Link]"));
[Link]("First Line");
[Link](); // Adds a new line (like pressing Enter)
[Link]("Second Line");
[Link]();
[Link]("Third Line");
[Link](); // Flushes the buffer and saves
}
}
Stream Type Speed
FileReader / FileWriter Slower (1 char at a time)
BufferedReader / BufferedWriter Faster (large chunk at a time)
10. Exception Handling in File Operations
File operations can fail (file not found, disk full, no permission). We handle this with try-catch.
import [Link].*;
class SafeFileRead {
public static void main(String[] args) {
try {
FileReader fr = new FileReader("[Link]");
int i;
while ((i = [Link]()) != -1) {
[Link]((char) i);
}
[Link]();
} catch (FileNotFoundException e) {
[Link]("Error: File not found! " + [Link]());
} catch (IOException e) {
[Link]("Error reading file: " + [Link]());
}
}
}
Exception Handling Explanation:
FileNotFoundException → Thrown when the file does not exist on disk
IOException → Thrown for any other I/O error (disk full, permissions, etc.)
try { } → Place risky code here
catch { } → Handle the error gracefully instead of crashing
Without try-catch, if file is missing the program CRASHES with an ugly error.
APPLET PROGRAMMING IN JAVA
1. What is an Applet?
An Applet is a special Java program that is designed to run inside a web browser or an Applet Viewer.
Unlike normal Java programs, applets do not run from the command line.
Think of an Applet like a small interactive widget embedded in a webpage.
Example: An online calculator, an animated game, or a drawing tool embedded in a webpage.
Applets were widely used in the early days of the internet (1990s-2000s).
Note: Applets are now deprecated (officially removed) in modern Java and browsers.
But they are still important for BCA/MCA examinations!
Key Features of Applets:
• Runs on the CLIENT side (in the user's browser)
• Embedded inside HTML pages using the <applet> tag
• Does NOT have a main() method — uses lifecycle methods instead
• Runs in a SANDBOX — restricted environment for security
• Requires a browser or Applet Viewer to run
2. Types of Applets
Type Description
Local Applet Stored and run from the local machine. No
internet needed. Used during development and
testing.
Remote Applet Stored on a remote web server. Downloaded
via the internet when the web page loads. Used
in live websites.
Simple Analogy:
Local Applet = Watching a movie from your own hard drive
Remote Applet = Streaming a movie from Netflix (downloaded from internet)
3. Java Application vs Java Applet
Feature Java Application Java Applet
Entry Point main() method required No main() method
Execution Environment JVM (Command Line) Browser / Applet Viewer
Security Full system access Restricted (Sandbox)
File Access Can read/write files freely Cannot access local files
Network Access Unrestricted Can only contact origin server
Starting Point java ClassName <applet> tag in HTML
4. Applet Life Cycle — The 5 Stages
Every applet goes through a defined set of stages from creation to destruction. These are called the Life
Cycle Methods.
Life Cycle Flow:
1. init() → Called ONCE when applet first loads
2. start() → Called when applet becomes visible/active
3. paint() → Called to draw content on screen
4. stop() → Called when applet is hidden or paused
5. destroy() → Called ONCE when applet is permanently removed
Stage 1: init() — Initialization
• Called only ONCE when the applet is first loaded
• Used for: setting up variables, loading images, initializing data
• Think of it like the constructor of the applet
public void init() {
// This runs only once when the page first loads
setBackground([Link]); // Set background color
[Link]("Applet initialized!");
}
Stage 2: start() — Starting
• Called every time the applet becomes visible or active
• Called AFTER init() — and also called when user returns to the page
• Used for: starting animations, resuming threads
public void start() {
// Called when user visits the page (can be multiple times)
[Link]("Applet started!");
}
Stage 3: paint(Graphics g) — Displaying
• Called every time the applet needs to draw/redraw on screen
• Takes a Graphics object 'g' as parameter — used for drawing
• Called automatically by the browser when the screen needs refresh
public void paint(Graphics g) {
// g is the Graphics object — our drawing tool
[Link]("Hello World", 50, 50); // Draw text at (x=50, y=50)
[Link](10, 80, 200, 80); // Draw a line
[Link]([Link]); // Change drawing color
[Link](30, 100, 100, 50); // Draw rectangle
}
Stage 4: stop() — Pausing
• Called when user navigates AWAY from the page (applet becomes hidden)
• Used for: pausing animations, suspending threads
• Opposite of start()
public void stop() {
// Called when user navigates away from the page
[Link]("Applet paused!");
}
Stage 5: destroy() — Cleanup
• Called only ONCE when the applet is permanently removed from memory
• Used for: releasing resources, closing connections
• Like a destructor — clean up everything before shutdown
public void destroy() {
// Called when applet is permanently closed
[Link]("Applet destroyed — cleaning up!");
}
Complete Life Cycle Summary:
Method Called When? Purpose
init() Once, at the start Initialize variables, load
resources
start() Every time page is visited Start animations, threads
paint(Graphics g) Whenever screen needs Draw text, shapes, images
drawing
stop() When page is hidden/left Pause animations, threads
destroy() Once, at the end Release resources, cleanup
5. Creating Your First Applet — Full Example
import [Link]; // Required: import Applet class
import [Link]; // Required: import Graphics for drawing
import [Link]; // Optional: for colors
import [Link]; // Optional: for fonts
// public class MUST match the filename ([Link])
public class MyApplet extends Applet { // 'extends Applet' is mandatory
// Stage 1: Called once when applet loads
public void init() {
setBackground([Link]); // Sets background to cyan color
[Link]("init() called");
}
// Stage 2: Called every time applet becomes active
public void start() {
[Link]("start() called");
}
// Stage 3: Called to draw on screen
public void paint(Graphics g) {
// Set font: Arial, Bold, 20pt
[Link](new Font("Arial", [Link], 20));
[Link]([Link]);
[Link]("Hello from Applet!", 50, 60); // Text at x=50, y=60
[Link]([Link]);
[Link](50, 80, 200, 100); // Rectangle: x=50, y=80, w=200, h=100
[Link]([Link]);
[Link](80, 100, 60, 60); // Filled circle/oval
}
// Stage 4: Called when page is left
public void stop() {
[Link]("stop() called");
}
// Stage 5: Called when applet is removed
public void destroy() {
[Link]("destroy() called");
}
}
Important Points:
The class MUST extend Applet ([Link])
The class name MUST match the Java filename exactly
Graphics object 'g' is automatically provided by the browser
Coordinates in Graphics are (x, y) from the TOP-LEFT corner of applet
No main() method is needed — the browser calls init/start/paint automatically
6. Common Graphics Methods for Drawing
Method Syntax Description
drawString() [Link]("text", x, y) Draw text at position (x,y)
drawLine() [Link](x1,y1,x2,y2) Draw a line between two
points
drawRect() [Link](x,y,w,h) Draw an empty rectangle
fillRect() [Link](x,y,w,h) Draw a filled rectangle
drawOval() [Link](x,y,w,h) Draw an empty oval/circle
fillOval() [Link](x,y,w,h) Draw a filled oval/circle
setColor() [Link]([Link]) Set the drawing color
setFont() [Link](new Font(...)) Set the text font/size
7. Running Applet Using HTML <applet> Tag
After compiling the applet, we embed it in an HTML file using the <applet> tag. Then open this HTML file
in a browser or Applet Viewer.
Step 1: Compile the Java file
javac [Link]
// This creates [Link]
Step 2: Create an HTML file ([Link])
<html>
<head>
<title>My First Applet</title>
</head>
<body>
<h2>Applet Demo</h2>
<!-- The applet tag embeds the Java applet into the webpage -->
<applet code="[Link]" <!-- The compiled class file -->
width="400" <!-- Width of applet in pixels -->
height="300"> <!-- Height of applet in pixels -->
</applet>
</body>
</html>
Step 3: Run using Applet Viewer
appletviewer [Link]
// appletviewer is a tool that comes with JDK
// Modern browsers no longer support the applet tag
Attributes of the <applet> Tag:
Attribute Description
code Name of the compiled .class file to run
width Width of the applet window in pixels
height Height of the applet window in pixels
codebase Optional: folder where .class file is located
alt Text shown if browser doesn't support applet
name Gives a name to the applet for JavaScript
access
8. Passing Parameters to Applet
We can pass values from HTML to the applet using <param> tags. This makes the applet dynamic.
HTML file with parameters:
<applet code="[Link]" width="300" height="200">
<param name="message" value="Hello from HTML!">
<param name="color" value="blue">
</applet>
Java Applet reading parameters:
public class ParamApplet extends Applet {
String msg;
public void init() {
// getParameter() reads the value from HTML <param> tag
msg = getParameter("message");
// If parameter not found, use a default value
if (msg == null) {
msg = "Default Message";
}
}
public void paint(Graphics g) {
[Link](msg, 50, 50); // Displays the parameter value
}
}
9. Final Quick Revision — Key Points
UNIT — FILE HANDLING REVISION:
Stream = flow of data between program and file
Byte Stream = for binary files (images/videos); uses FileInputStream / FileOutputStream
Character Stream = for text files; uses FileReader / FileWriter
File class = represents file on disk; methods: createNewFile(), exists(), delete()
FileWriter = write text; use (file, true) for append mode
FileReader = read text; read() returns -1 at end of file
BufferedReader/Writer = faster version; readLine() reads whole line
Always call close() after file operations to save data!
UNIT 2 — APPLET PROGRAMMING REVISION:
Applet = small Java program that runs inside a web browser
Types: Local Applet (from local machine), Remote Applet (from internet)
Life Cycle: init() → start() → paint() → stop() → destroy()
init() = called ONCE for setup
start() = called EVERY TIME applet becomes visible
paint(Graphics g) = called to draw on screen
stop() = called when page is left
destroy() = called ONCE for cleanup
HTML: use <applet code='[Link]' width=300 height=200></applet>
Run using: appletviewer [Link]