☕ Java Deep Dive Series

Static Keyword
& Static Class

Complete theory se leke real backend patterns tak — sab kuch ek jagah

static variable static method static block static nested class static import inheritance design patterns

📚 Table of Contents

Static Keyword — Foundation Theory

Java mein static ka mool concept — memory se leke behaviour tak

🔰 Static Kya Hai? (What is Static?)

Static ka matlab hai — "Class ka member, Object ka nahi." Jab kisi variable, method, block, ya class ko static keyword se mark karte hain, toh woh class se directly associated ho jaata hai, na ki kisi particular object se.

Normal (non-static) members ko access karne ke liye pehle object banana padta hai. Static members ko class name se directly access kiya jaata hai — object ki koi zaroorat nahi hoti.

Memory mein kahan store hota hai? Static members Method Area (ya Class Area) mein store hote hain, jabki instance variables Heap mein har object ke saath store hote hain. Isliye static ka ek hi copy hota hai — chahe aap 1 object banao ya 1000.

STATIC vs INSTANCE — Memory Diagram ┌─────────────────────────────────────────────────────────────────────┐ │ METHOD AREA / CLASS AREA (JVM) │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ static int count = 3; ← sirf EK copy │ │ │ │ static String college = "IIT" ← sab share karte hain │ │ │ └─────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────┐ │ HEAP MEMORY (Objects) │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ s1 (Object) │ │ s2 (Object) │ │ s3 (Object) │ │ │ │ name=Rahul │ │ name=Amit │ │ name=Priya │ │ │ │ age=21 │ │ age=22 │ │ age=20 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ↑ ↑ ↑ │ │ └───────────────────┴───────────────────┘ │ │ Teeno same static variable share karte hain! │ └─────────────────────────────────────────────────────────────────────┘ STATIC keyword 5 jagah use hota hai: 1. static variable → Shared class-level data 2. static method → Object ke bina call karo 3. static block → Class load hote waqt ek baar execute 4. static class → Outer object ke bina nested class 5. static import → Class name likhne ki zaroorat nahi
Class Level
Static members class ke saath belong karte hain, kisi specific object ke saath nahi
Single Copy
Memory mein sirf ek copy — chahe 0 objects hon ya 1000, value same jagah hai
Early Loading
Class load hote hi static members available ho jaate hain — object banana zaroori nahi
Shared State
Sabhi objects ek hi static variable ko share karte hain — koi bhi badlay toh sab ko effect hoga
📦

Topic 1 — Static Variable (Class Variable)

Class-level shared data — ek copy, sab share karte hain

📖 Theory: Static Variable Kya Hai?

Static variable ko class variable bhi kehte hain. Yeh class ke saath associate hota hai, na ki kisi object ke saath. JVM mein class load hote hi yeh variable Method Area mein create ho jaata hai aur program ke end tak wahan rehta hai.

Key Characteristics:

  • Single copy: Puri JVM mein sirf ek hi copy hoti hai. Chahe 100 objects banao — sab usi ek variable ko share karte hain.
  • Class se access: Best practice hai ClassName.variable se access karna. Object se bhi ho sakta hai (obj.variable) lekin misleading lagta hai aur IDE warning deta hai.
  • Default values: Instance variables ki tarah static variables ko bhi default values milti hain (int=0, boolean=false, object=null).
  • Lifetime: Class load se leke class unload (JVM shutdown) tak — ye sabse lambi lifetime hai Java mein.

Kab use karein? Jab ek value sabhi objects ke liye same ho — jaise bank ka naam, company ka naam, object counter, shared configuration values, constants (static final).

📋 Static Variable — Rules & Important Points
  • Access: ClassName.variable ← best; obj.variable ← allowed but misleading
  • Memory: Method Area mein store hota hai, Heap mein nahi
  • Scope: Class ke andar kahin bhi accessible — static aur instance dono methods mein
  • Constant: static final = constant — convention: ALL_CAPS naam (jaise MAX_SIZE)
  • Thread Safety: Multiple threads ek hi static variable change kar sakti hain — synchronization zaroori
  • Override: Static variables override nahi hote — sirf hide hote hain (child mein same naam ka variable)
STATIC VARIABLE — Memory & Access Diagram class Student { static String college = "IIT Delhi"; ← Method Area mein String name; ← Har object ke Heap mein int rollNo; } Student s1 = new Student("Rahul", 101); Student s2 = new Student("Amit", 102); Student s3 = new Student("Priya", 103); METHOD AREA ┌──────────────────────┐ │ college = "IIT Delhi" │ ← sirf ek copy └──────────────────────┘ ↑ ↑ ↑ │ │ │ (sab yahan point karte hain) HEAP: s1 s2 s3 name=Rahul name=Amit name=Priya rollNo=101 rollNo=102 rollNo=103 college change karo → sabhi ko effect! Student.college = "NIT Surat"; s1.college → "NIT Surat" ✓ s2.college → "NIT Surat" ✓ (same memory location!) s3.college → "NIT Surat" ✓
📁 Program 1 — Object Counter with Static Variable P1.1
Static variable se count karo kitne objects bane hain. Instance vs static ka basic difference dekho.
public class StaticVariable1 {

    // ── Static variable: sabhi objects share karte hain ──
    static int objectCount = 0;

    // ── Instance variables: har object ka apna ──
    String name;
    int age;

    // Constructor: har baar object banta hai toh count badhta hai
    StaticVariable1(String name, int age) {
        this.name = name;
        this.age  = age;
        objectCount++;  // shared counter — ek jagah badha, sab ko effect
        System.out.println("✔ Object created: " + name +
                           " | Total now: " + objectCount);
    }

    public static void main(String[] args) {

        // Object banne se pehle bhi static variable exist karta hai!
        System.out.println("Before any object: count = " + objectCount);

        StaticVariable1 s1 = new StaticVariable1("Rahul", 21);
        StaticVariable1 s2 = new StaticVariable1("Amit",  22);
        StaticVariable1 s3 = new StaticVariable1("Priya", 20);

        System.out.println("\n── After 3 objects ──");
        // Teeno same value dikhate hain — same memory!
        System.out.println("Class access  : StaticVariable1.objectCount = " + StaticVariable1.objectCount);
        System.out.println("Via s1        : s1.objectCount              = " + s1.objectCount);
        System.out.println("Via s2        : s2.objectCount              = " + s2.objectCount);

        System.out.println("\n── Instance variables alag-alag hain ──");
        System.out.println("s1.name = " + s1.name + " | s2.name = " + s2.name);
    }
}
▶ OUTPUT
Before any object: count = 0
✔ Object created: Rahul | Total now: 1
✔ Object created: Amit  | Total now: 2
✔ Object created: Priya | Total now: 3

── After 3 objects ──
Class access  : StaticVariable1.objectCount = 3
Via s1        : s1.objectCount              = 3
Via s2        : s2.objectCount              = 3

── Instance variables alag-alag hain ──
s1.name = Rahul | s2.name = Amit
📁 Program 2 — Bank Account: Shared vs Individual Data P1.2
Real-world example: Bank name aur interest rate static (sab share karte hain), account holder aur balance instance (har account ka apna).
class BankAccount {

    // ── Static: sabhi accounts ka ek hi bank, ek hi rate ──
    static String bankName    = "State Bank of India";
    static double interestRate = 7.5;  // RBI set karta hai — sab pe laagu

    // ── Instance: har account ka apna data ──
    String accountHolder;
    long   accountNumber;
    double balance;

    BankAccount(String holder, long accNo, double balance) {
        this.accountHolder = holder;
        this.accountNumber = accNo;
        this.balance       = balance;
    }

    double calculateInterest() {
        return balance * interestRate / 100;  // static rate use karta hai
    }

    void showDetails() {
        System.out.println("Bank     : " + bankName);           // static
        System.out.println("Holder   : " + accountHolder);      // instance
        System.out.println("Acc No   : " + accountNumber);      // instance
        System.out.println("Balance  : ₹" + balance);           // instance
        System.out.println("Rate     : " + interestRate + "%"); // static
        System.out.println("Interest : ₹" + calculateInterest());
        System.out.println("─".repeat(40));
    }

    public static void main(String[] args) {
        BankAccount a1 = new BankAccount("Rahul Sharma", 10012345L, 50000);
        BankAccount a2 = new BankAccount("Priya Singh",  10067890L, 80000);

        System.out.println("═══ Before Rate Change ═══");
        a1.showDetails();
        a2.showDetails();

        // RBI ne rate change kiya → SABHI accounts affect!
        System.out.println("📢 RBI ne interest rate 7.5% → 8.5% kiya!\n");
        BankAccount.interestRate = 8.5;  // class se change karo

        System.out.println("═══ After Rate Change ═══");
        a1.showDetails();  // naya rate automatically reflect
        a2.showDetails();  // ← dono ek hi static variable share karte hain
    }
}
▶ OUTPUT
═══ Before Rate Change ═══
Bank     : State Bank of India
Holder   : Rahul Sharma
Acc No   : 10012345
Balance  : ₹50000.0
Rate     : 7.5%
Interest : ₹3750.0
────────────────────────────────────────
Bank     : State Bank of India
Holder   : Priya Singh
Acc No   : 10067890
Balance  : ₹80000.0
Rate     : 7.5%
Interest : ₹6000.0
────────────────────────────────────────
📢 RBI ne interest rate 7.5% → 8.5% kiya!

═══ After Rate Change ═══
Bank     : State Bank of India
Holder   : Rahul Sharma  |  Rate: 8.5%  |  Interest: ₹4250.0
...
Bank     : State Bank of India
Holder   : Priya Singh   |  Rate: 8.5%  |  Interest: ₹6800.0
📁 Program 3 — Static Constants (static final) P1.3
static final se constants banao — change nahi ho sakte, har jagah ek value. Java mein Math.PI, Integer.MAX_VALUE isi tarah banaye hain.
class AppConstants {

    // static final = CONSTANT — convention: ALL_CAPS naam
    // Memory mein sirf ek copy, change nahi ho sakti
    static final double PI        = 3.14159265358979;
    static final int    MAX_USERS = 1000;
    static final String APP_NAME  = "JavaMaster";
    static final String VERSION   = "v2.0.1";
    static final String DB_URL    = "jdbc:mysql://localhost:3306/mydb";
    static final double TAX_RATE  = 0.18;  // GST 18%

    // Static mutable variable (constant nahi)
    static int   activeUsers  = 0;
    static String environment = "development";

    // Static method — constant use karta hai
    static double circleArea(double r) {
        return PI * r * r;  // constant directly use
    }

    static double addTax(double amount) {
        return amount + (amount * TAX_RATE);
    }

    public static void main(String[] args) {
        System.out.println("App     : " + AppConstants.APP_NAME);
        System.out.println("Version : " + AppConstants.VERSION);
        System.out.println("DB      : " + AppConstants.DB_URL);
        System.out.println("Max     : " + AppConstants.MAX_USERS + " users");

        System.out.println("\n── Calculations ──");
        System.out.printf("Circle area (r=7): %.4f%n", AppConstants.circleArea(7));
        System.out.printf("Price ₹500 + GST : ₹%.2f%n", AppConstants.addTax(500));

        // Mutable static
        AppConstants.activeUsers = 150;
        System.out.println("\nActive users: " + AppConstants.activeUsers);

        // ❌ AppConstants.PI = 3.0; → COMPILE ERROR! final change nahi hota
        System.out.println("\nPI = " + AppConstants.PI + " (cannot change — final!)");
    }
}
▶ OUTPUT
App     : JavaMaster
Version : v2.0.1
DB      : jdbc:mysql://localhost:3306/mydb
Max     : 1000 users

── Calculations ──
Circle area (r=7): 153.9380
Price ₹500 + GST : ₹590.00

Active users: 150

PI = 3.14159265358979 (cannot change — final!)
📁 Program 4 — Singleton Pattern with Static Variable P1.4
Static variable se sirf ek hi object ensure karo (Singleton Design Pattern) — DB connection, Logger, Config isi pattern se banate hain.
class DatabaseConnection {

    // private static — sirf ek instance store karta hai
    private static DatabaseConnection instance = null;
    private static int connectionCount = 0;

    private String url;
    private boolean connected;

    // private constructor — bahar se new nahi bana sakte!
    private DatabaseConnection() {
        this.url       = "jdbc:mysql://localhost:3306/mydb";
        this.connected = true;
        connectionCount++;
        System.out.println("🔗 DB Connection established! [Count: " + connectionCount + "]");
    }

    // static factory method — getInstance
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            System.out.println("📦 Creating new connection...");
            instance = new DatabaseConnection();
        } else {
            System.out.println("♻  Returning existing connection");
        }
        return instance;
    }

    void executeQuery(String sql) {
        System.out.println("⚡ Executing: " + sql);
    }

    public static void main(String[] args) {
        System.out.println("=== Request 1: Login ===");
        DatabaseConnection db1 = DatabaseConnection.getInstance();
        db1.executeQuery("SELECT * FROM users WHERE id=1");

        System.out.println("\n=== Request 2: Dashboard ===");
        DatabaseConnection db2 = DatabaseConnection.getInstance();
        db2.executeQuery("SELECT COUNT(*) FROM orders");

        System.out.println("\n=== Request 3: Profile ===");
        DatabaseConnection db3 = DatabaseConnection.getInstance();
        db3.executeQuery("SELECT * FROM profiles WHERE user_id=1");

        System.out.println("\n── Verification ──");
        System.out.println("db1 == db2? " + (db1 == db2));  // true! same object
        System.out.println("db2 == db3? " + (db2 == db3));  // true!
        System.out.println("Total connections created: " + connectionCount); // 1 only!
    }
}
▶ OUTPUT
=== Request 1: Login ===
📦 Creating new connection...
🔗 DB Connection established! [Count: 1]
⚡ Executing: SELECT * FROM users WHERE id=1

=== Request 2: Dashboard ===
♻  Returning existing connection
⚡ Executing: SELECT COUNT(*) FROM orders

=== Request 3: Profile ===
♻  Returning existing connection
⚡ Executing: SELECT * FROM profiles WHERE user_id=1

── Verification ──
db1 == db2? true
db2 == db3? true
Total connections created: 1
📁 Program 5 — Vehicle Registry: Complete Comparison P1.5
Static aur instance variables ka complete side-by-side comparison — kab kya use karna chahiye.
class Vehicle {

    // ── STATIC (class-level, shared) ──
    static String  manufacturer = "Tata Motors";
    static int     totalVehicles = 0;
    static double  averagePrice  = 0;

    // ── INSTANCE (object-level, individual) ──
    String model;
    int    year;
    double price;
    String color;

    Vehicle(String model, int year, double price, String color) {
        this.model = model;
        this.year  = year;
        this.price = price;
        this.color = color;

        // Static update — har naye vehicle pe
        totalVehicles++;
        averagePrice = ((averagePrice * (totalVehicles-1)) + price) / totalVehicles;
    }

    void info() {
        System.out.printf("  %-10s | %d | ₹%-9.0f | %-10s | By: %s%n",
                           model, year, price, color, manufacturer);
    }

    public static void main(String[] args) {
        Vehicle v1 = new Vehicle("Nexon",   2023, 900000,  "Red");
        Vehicle v2 = new Vehicle("Punch",   2022, 700000,  "Blue");
        Vehicle v3 = new Vehicle("Safari",  2024, 1800000, "White");
        Vehicle v4 = new Vehicle("Harrier", 2023, 1500000, "Black");

        System.out.println("  Model      | Year | Price     | Color      | Maker");
        System.out.println("  " + "─".repeat(58));
        v1.info(); v2.info(); v3.info(); v4.info();

        System.out.println("\n── Static Summary (Shared Data) ──");
        System.out.println("Manufacturer    : " + Vehicle.manufacturer);
        System.out.println("Total Vehicles  : " + Vehicle.totalVehicles);
        System.out.printf ("Average Price   : ₹%.0f%n", Vehicle.averagePrice);

        // Static change → sabhi objects affect!
        Vehicle.manufacturer = "Tata Motors Ltd.";
        System.out.println("\nAfter name change:");
        v1.info();  // updated manufacturer
        v4.info();  // updated manufacturer
    }
}
▶ OUTPUT
  Model      | Year | Price     | Color      | Maker
  ──────────────────────────────────────────────────────────
  Nexon      | 2023 | ₹900000   | Red        | By: Tata Motors
  Punch      | 2022 | ₹700000   | Blue       | By: Tata Motors
  Safari     | 2024 | ₹1800000  | White      | By: Tata Motors
  Harrier    | 2023 | ₹1500000  | Black      | By: Tata Motors

── Static Summary (Shared Data) ──
Manufacturer    : Tata Motors
Total Vehicles  : 4
Average Price   : ₹1225000

After name change:
  Nexon      | 2023 | ₹900000   | Red        | By: Tata Motors Ltd.
  Harrier    | 2023 | ₹1500000  | Black      | By: Tata Motors Ltd.

Topic 2 — Static Method

Object banaye bina call karo — utility, factory, helper patterns

📖 Theory: Static Method Kya Hai?

Static method woh method hai jo class ke saath belong karta hai, kisi particular object ke saath nahi. Ise call karne ke liye object create karne ki zaroorat nahi — sirf class name use karo: ClassName.methodName().

Static method ke rules (bahut important!):

  • ✅ Static method → static variable access kar sakta hai
  • ✅ Static method → doosre static method ko call kar sakta hai
  • ❌ Static method → instance variable directly access nahi kar sakta
  • ❌ Static method → instance method call nahi kar sakta (directly)
  • ❌ Static method → this keyword use nahi kar sakta

Kyun? Kyunki static method tab bhi exist karta hai jab koi object nahi hota. Agar koi object hi nahi hai toh "this" ka kya matlab? Isliye static method object-specific cheezein access nahi kar sakta.

main() static kyun hai? JVM program start karte waqt koi object nahi banata. Isliye main() static hona chahiye taaki JVM directly ClassName.main(args) call kar sake.

Kab use karein? Utility/helper operations ke liye — Math.sqrt(), Integer.parseInt(), Arrays.sort() — ye sab static methods hain! Jab method ko kisi particular object ke state ki zaroorat nahi ho.

✅ Static Method Kar Sakta Hai

  • Static variables read/write karna
  • Doosre static methods call karna
  • Local variables use karna
  • Objects create karke unka use karna
  • Parameters lena aur return karna
  • synchronized hona (class-level lock)

❌ Static Method Nahi Kar Sakta

  • Instance variables directly access karna
  • Instance methods directly call karna
  • this keyword use karna
  • super keyword use karna
  • Override hona (sirf hide hota hai)
  • Abstract hona
📁 Program 1 — Static vs Instance Method Basics P2.1
Static aur instance methods ka fundamental difference dekho — kab kya accessible hai aur kab nahi.
public class StaticMethodBasics {

    static int  count = 0;   // static — class level
    String      name;         // instance — object level

    StaticMethodBasics(String name) {
        this.name = name;
        count++;
    }

    // ── Static Method ──
    static void showCount() {
        System.out.println("Objects created: " + count);  // ✅ static access
        // name = "test"; ← COMPILE ERROR! instance var nahi
        // greet();       ← COMPILE ERROR! instance method nahi
    }

    static int add(int a, int b)       { return a + b; }
    static boolean isPositive(int n)   { return n > 0; }
    static String repeat(String s, int n) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; i++) sb.append(s);
        return sb.toString();
    }

    // ── Instance Method ── (object chahiye)
    void greet() {
        // instance method: dono access kar sakta hai
        System.out.println("Hello from " + name + " | Total: " + count);
        showCount();  // ✅ instance method static ko call kar sakta hai
    }

    public static void main(String[] args) {
        // Object banaye bina static call!
        StaticMethodBasics.showCount();
        System.out.println("add(10,5) = " + add(10, 5));
        System.out.println("isPositive(-3) = " + isPositive(-3));
        System.out.println("repeat(\"Ha\",3) = " + repeat("Ha", 3));

        // Objects banao
        StaticMethodBasics s1 = new StaticMethodBasics("Rahul");
        StaticMethodBasics s2 = new StaticMethodBasics("Priya");
        s1.greet();
        s2.greet();
        showCount(); // 2
    }
}
▶ OUTPUT
Objects created: 0
add(10,5) = 15
isPositive(-3) = false
repeat("Ha",3) = HaHaHa
Hello from Rahul | Total: 1
Objects created: 1
Hello from Priya | Total: 2
Objects created: 2
Objects created: 2
📁 Program 2 — Utility Class Pattern (Math Class jaisi) P2.2
Pure static utility class banao — Java ki Math class jaisi. Private constructor daalo taaki object na bane.
class MathUtils {

    // Private constructor — object banana allowed nahi!
    // Ye pure utility class hai, sirf static methods ke liye
    private MathUtils() {
        throw new UnsupportedOperationException("Utility class!");
    }

    static int    abs(int n)            { return n < 0 ? -n : n; }
    static double power(double b, int e) {
        double r = 1;
        for (int i = 0; i < e; i++) r *= b;
        return r;
    }
    static boolean isPrime(int n) {
        if (n < 2) return false;
        for (int i = 2; i * i <= n; i++)
            if (n % i == 0) return false;
        return true;
    }
    static int factorial(int n) {
        if (n <= 1) return 1;
        return n * factorial(n - 1);  // recursive static!
    }
    static int gcd(int a, int b)        { return b == 0 ? a : gcd(b, a % b); }
    static int lcm(int a, int b)        { return a / gcd(a, b) * b; }
    static double percentage(double val, double total) { return (val / total) * 100; }
    static int clamp(int val, int min, int max) {
        return Math.max(min, Math.min(max, val));
    }

    public static void main(String[] args) {
        // Koi object nahi! Seedha class name se:
        System.out.println("abs(-42)         = " + MathUtils.abs(-42));
        System.out.println("power(2,10)      = " + MathUtils.power(2, 10));
        System.out.println("factorial(7)     = " + MathUtils.factorial(7));
        System.out.println("isPrime(97)      = " + MathUtils.isPrime(97));
        System.out.println("isPrime(100)     = " + MathUtils.isPrime(100));
        System.out.println("gcd(48,18)       = " + MathUtils.gcd(48, 18));
        System.out.println("lcm(4,6)         = " + MathUtils.lcm(4, 6));
        System.out.println("percentage(45,60)= " + MathUtils.percentage(45, 60) + "%");
        System.out.println("clamp(150,0,100) = " + MathUtils.clamp(150, 0, 100));
    }
}
▶ OUTPUT
abs(-42)         = 42
power(2,10)      = 1024.0
factorial(7)     = 5040
isPrime(97)      = true
isPrime(100)     = false
gcd(48,18)       = 6
lcm(4,6)         = 12
percentage(45,60)= 75.0%
clamp(150,0,100) = 100
📁 Program 3 — Static Factory Method Pattern P2.3
Static factory methods se different types ke objects banao — constructors se zyada expressive aur flexible.
class User {

    private String username;
    private String email;
    private String role;
    private boolean active;

    // Private constructor — sirf class ke andar se call hoga
    private User(String username, String email, String role) {
        this.username = username;
        this.email    = email;
        this.role     = role;
        this.active   = true;
        System.out.println("✔ Created [" + role + "] user: " + username);
    }

    // ── Static Factory Methods ──
    // Naam se clear hai kya ban raha hai — constructor se better!
    static User createAdmin(String username, String email) {
        return new User(username, email, "ADMIN");
    }
    static User createCustomer(String username, String email) {
        return new User(username, email, "CUSTOMER");
    }
    static User createModerator(String username, String email) {
        return new User(username, email, "MODERATOR");
    }
    static User createGuest() {
        String tempName = "guest_" + System.currentTimeMillis() % 10000;
        return new User(tempName, tempName + "@temp.com", "GUEST");
    }

    // Static validation method
    static boolean isValidEmail(String email) {
        return email != null
            && email.contains("@")
            && email.indexOf("@") > 0
            && email.contains(".");
    }
    static boolean isValidUsername(String u) {
        return u != null && u.length() >= 4 && u.matches("[a-zA-Z0-9_]+");
    }

    void display() {
        System.out.printf("  User: %-15s | Role: %-10s | Active: %b%n",
                           username, role, active);
    }

    public static void main(String[] args) {
        System.out.println("── Validation First ──");
        String email = "rahul@company.com";
        System.out.println("Email valid? " + isValidEmail(email));
        System.out.println("Username valid? " + isValidUsername("rk"));   // false (too short)
        System.out.println("Username valid? " + isValidUsername("rahul")); // true

        System.out.println("\n── Creating Users ──");
        User admin = User.createAdmin("superadmin", "admin@company.com");
        User cust  = User.createCustomer("rahul_k", "rahul@gmail.com");
        User mod   = User.createModerator("mod_priya", "priya@company.com");
        User guest = User.createGuest();

        System.out.println("\n── User List ──");
        admin.display(); cust.display(); mod.display(); guest.display();
    }
}
▶ OUTPUT
── Validation First ──
Email valid? true
Username valid? false
Username valid? true

── Creating Users ──
✔ Created [ADMIN] user: superadmin
✔ Created [CUSTOMER] user: rahul_k
✔ Created [MODERATOR] user: mod_priya
✔ Created [GUEST] user: guest_7342

── User List ──
  User: superadmin      | Role: ADMIN       | Active: true
  User: rahul_k         | Role: CUSTOMER    | Active: true
  User: mod_priya       | Role: MODERATOR   | Active: true
  User: guest_7342      | Role: GUEST       | Active: true
📁 Program 4 — String Utility: Static Methods Practice P2.4
Real-world string utility class — backend mein commonly used operations sab static methods se.
class StringUtils {
    private StringUtils() {}  // utility class — no instances

    // Reverse a string
    static String reverse(String s) {
        return new StringBuilder(s).reverse().toString();
    }

    // Check palindrome
    static boolean isPalindrome(String s) {
        s = s.toLowerCase().replaceAll("[^a-z0-9]", "");
        return s.equals(reverse(s));
    }

    // Count occurrences of a character
    static int countChar(String s, char c) {
        int count = 0;
        for (char ch : s.toCharArray()) if (ch == c) count++;
        return count;
    }

    // Capitalize first letter of each word
    static String titleCase(String s) {
        String[] words = s.toLowerCase().split(" ");
        StringBuilder sb = new StringBuilder();
        for (String w : words)
            sb.append(Character.toUpperCase(w.charAt(0))).append(w.substring(1)).append(" ");
        return sb.toString().trim();
    }

    // Mask sensitive data (e.g., email, phone)
    static String maskEmail(String email) {
        int at = email.indexOf('@');
        if (at < 2) return "***@" + email.substring(at + 1);
        return email.charAt(0) + "*".repeat(at - 2) + email.charAt(at-1) + email.substring(at);
    }

    static String maskPhone(String phone) {
        return phone.substring(0, 2) + "****" + phone.substring(6);
    }

    // Truncate with ellipsis
    static String truncate(String s, int maxLen) {
        return s.length() <= maxLen ? s : s.substring(0, maxLen - 3) + "...";
    }

    public static void main(String[] args) {
        System.out.println("reverse('Hello')     = " + StringUtils.reverse("Hello"));
        System.out.println("isPalindrome('racecar') = " + StringUtils.isPalindrome("racecar"));
        System.out.println("isPalindrome('A man a plan a canal Panama') = "
                          + StringUtils.isPalindrome("A man a plan a canal Panama"));
        System.out.println("countChar('banana','a') = " + StringUtils.countChar("banana", 'a'));
        System.out.println("titleCase('hello world java') = "
                          + StringUtils.titleCase("hello world java"));
        System.out.println("maskEmail('rahul@gmail.com') = "
                          + StringUtils.maskEmail("rahul@gmail.com"));
        System.out.println("maskPhone('9876543210') = "
                          + StringUtils.maskPhone("9876543210"));
        System.out.println("truncate('Hello World Java',10) = "
                          + StringUtils.truncate("Hello World Java", 10));
    }
}
▶ OUTPUT
reverse('Hello')     = olleH
isPalindrome('racecar') = true
isPalindrome('A man a plan a canal Panama') = true
countChar('banana','a') = 3
titleCase('hello world java') = Hello World Java
maskEmail('rahul@gmail.com') = r***l@gmail.com
maskPhone('9876543210') = 98****3210
truncate('Hello World Java',10) = Hello W...
📁 Program 5 — main() kyun static hai — Deep Explanation P2.5
JVM ka entry point samjho — main() static kyun, aur static vs instance method calling rules ka complete demo.
public class WhyMainIsStatic {

    static String appName = "JavaApp";
    int instanceId;
    static int nextId = 0;

    WhyMainIsStatic() {
        instanceId = ++nextId;
        showBanner();  // constructor mein static method call kar sakte hain ✅
    }

    // Static method calling another static
    static void showBanner() {
        System.out.println("╔══════════════════════════╗");
        System.out.println("║  " + appName + " - Starting Up   ║");
        System.out.println("╚══════════════════════════╝");
    }

    // Static method — calculations
    static int doubleIt(int n)    { return multiply(n, 2); }  // static → static ✅
    static int multiply(int a, int b) { return a * b; }

    // Instance method
    void showInstanceInfo() {
        // Instance method can access both
        System.out.println("Instance #" + instanceId + " of " + appName);
        showBanner();  // instance method → static method ✅
    }

    public static void main(String[] args) {
        /*
         * JVM karta hai: WhyMainIsStatic.main(args)
         * JVM ne koi object nahi banaya!
         * Isliye main() MUST be static — object ke bina call hona chahiye.
         *
         * Agar main() non-static hoti:
         * JVM ko pehle WhyMainIsStatic obj = new WhyMainIsStatic() banana padta
         * Lekin fir constructor call hota, aur object kaun banata? — Chicken-egg problem!
         */

        System.out.println("JVM ne main() directly call kiya — no object created yet!");
        System.out.println("appName = " + appName);  // static variable ✅

        // Instance methods call karna ho toh object banana padega
        WhyMainIsStatic obj1 = new WhyMainIsStatic();
        WhyMainIsStatic obj2 = new WhyMainIsStatic();
        obj1.showInstanceInfo();
        obj2.showInstanceInfo();

        System.out.println("\ndoubleIt(7) = " + doubleIt(7));   // static → static ✅
        System.out.println("nextId = " + nextId);              // static var ✅
    }
}
▶ OUTPUT
JVM ne main() directly call kiya — no object created yet!
appName = JavaApp
╔══════════════════════════╗
║  JavaApp - Starting Up   ║
╚══════════════════════════╝
╔══════════════════════════╗
║  JavaApp - Starting Up   ║
╚══════════════════════════╝
Instance #1 of JavaApp
JavaApp banner...
Instance #2 of JavaApp
JavaApp banner...

doubleIt(7) = 14
nextId = 2
🔥

Topic 3 — Static Block (Static Initializer)

Class load pe sirf ek baar — initialization logic ka perfect jagah

📖 Theory: Static Block Kya Hai?

Static block (ya Static Initializer Block) ek code block hai jo class mein static { } ke andar likha jaata hai. Yeh tab execute hota hai jab JVM class ko pehli baar load karta hai — aur sirf ek hi baar execute hota hai, chahe baad mein 100 objects banao.

Static block kab use karein?

  • Complex initialization: Jab static variable ko simple assignment se zyada complex logic se initialize karna ho
  • Exception handling: Static variable initialization mein exception handle karni ho (jo simple assignment mein possible nahi)
  • Configuration loading: Database config, properties file, drivers load karna
  • Lookup tables: Maps, arrays ko pre-populate karna

Execution Order (bahut important!):

  1. Static variables default values se initialize hote hain
  2. Static variables aur blocks top-to-bottom order mein execute hote hain
  3. Constructor execute hota hai (har object ke liye)
STATIC BLOCK — Execution Order class Demo { static int x = 10; // Step 1: x = 10 static { System.out.println("Block 1! x=" + x); // Step 2: "Block 1! x=10" x = 20; // x is now 20 } static int y = x + 5; // Step 3: y = 25 (x=20 after block) static { System.out.println("Block 2! y=" + y); // Step 4: "Block 2! y=25" } Demo() { System.out.println("Constructor!"); // Step 5: har object ke liye } } new Demo(); → Block 1! → Block 2! → Constructor! new Demo(); → Constructor! (blocks dobara nahi) new Demo(); → Constructor! (blocks dobara nahi) INHERITANCE mein: Parent.static_block → Child.static_block → Parent.constructor → Child.constructor
📁 Program 1 — Static Block Basic: One Time Execution P3.1
Static block sirf ek baar execute hota hai — proof dekho. Constructor har object ke liye, block sirf pehli baar.
public class StaticBlockBasic {

    static int x;
    static int y;
    static String message;

    // Static block — class load hote waqt SIRF EK BAAR
    static {
        System.out.println("══ Static Block Executing ══");
        x       = 100;
        y       = 200;
        message = "Initialized in static block";
        System.out.println("x=" + x + ", y=" + y);
        System.out.println("Static block DONE!\n");
    }

    int instanceVar;

    // Constructor — har object ke liye
    StaticBlockBasic(int val) {
        this.instanceVar = val;
        System.out.println("Constructor called! instanceVar=" + val
                         + " | x=" + x + " (static)");
    }

    public static void main(String[] args) {
        System.out.println("main() start\n");  // Note: static block already ran!

        System.out.println("Creating object 1:");
        StaticBlockBasic obj1 = new StaticBlockBasic(10);

        System.out.println("\nCreating object 2:");
        StaticBlockBasic obj2 = new StaticBlockBasic(20);

        System.out.println("\nCreating object 3:");
        StaticBlockBasic obj3 = new StaticBlockBasic(30);

        System.out.println("\nFinal: x=" + x + " | message=" + message);
        System.out.println("Note: Static block ran only ONCE, constructor ran 3 times!");
    }
}
▶ OUTPUT
══ Static Block Executing ══
x=100, y=200
Static block DONE!

main() start

Creating object 1:
Constructor called! instanceVar=10 | x=100 (static)

Creating object 2:
Constructor called! instanceVar=20 | x=100 (static)

Creating object 3:
Constructor called! instanceVar=30 | x=100 (static)

Final: x=100 | message=Initialized in static block
Note: Static block ran only ONCE, constructor ran 3 times!
📁 Program 2 — Multiple Static Blocks & Order P3.2
Multiple static blocks hote hain toh kaunsa pehle? Top-to-bottom order — strict rule.
public class MultipleStaticBlocks {

    // Variables and blocks execute in TOP-TO-BOTTOM order
    static int a = initA();  // method call for initialization

    static {
        System.out.println("Static Block #1: a=" + a);
        a = a * 2;  // a was 5, now 10
        System.out.println("Static Block #1 end: a=" + a);
    }

    static int b = a + 5;   // b = 10+5 = 15 (after block #1)

    static {
        System.out.println("Static Block #2: a=" + a + ", b=" + b);
        b = b * 2;  // b = 30
        System.out.println("Static Block #2 end: b=" + b);
    }

    static int c = a + b;   // c = 10+30 = 40 (after both blocks)

    // Static method used for initialization
    static int initA() {
        System.out.println("initA() called — a initializing to 5");
        return 5;
    }

    public static void main(String[] args) {
        System.out.println("\n── main() executing ──");
        System.out.println("a = " + a);  // 10
        System.out.println("b = " + b);  // 30
        System.out.println("c = " + c);  // 40
        System.out.println("\nConclusion: Execution order = top to bottom!");
    }
}
▶ OUTPUT
initA() called — a initializing to 5
Static Block #1: a=5
Static Block #1 end: a=10
Static Block #2: a=10, b=15
Static Block #2 end: b=30

── main() executing ──
a = 10
b = 30
c = 40

Conclusion: Execution order = top to bottom!
📁 Program 3 — Config Loading: Real Backend Use Case P3.3
Static block se application config load karo — Spring Boot, Jakarta EE sab isi concept pe kaam karte hain.
class AppConfig {

    // final constants — static block se initialize karenge
    static final String DB_HOST;
    static final int    DB_PORT;
    static final String DB_NAME;
    static final int    POOL_SIZE;
    static final String LOG_LEVEL;
    static final String BASE_URL;
    static boolean      configLoaded = false;

    // Static block: real world mein environment variables ya properties file se padha jaata
    static {
        System.out.println("[BOOT] Loading application configuration...");
        try {
            // Simulate: properties file / env variables read karna
            DB_HOST   = System.getenv("DB_HOST")   != null ? System.getenv("DB_HOST") : "localhost";
            DB_PORT   = 3306;
            DB_NAME   = "backend_app";
            POOL_SIZE = 10;
            LOG_LEVEL = "INFO";
            BASE_URL  = "https://api.myapp.com/v1";
            configLoaded = true;

            System.out.println("[BOOT] ✔ DB_HOST   : " + DB_HOST);
            System.out.println("[BOOT] ✔ DB_PORT   : " + DB_PORT);
            System.out.println("[BOOT] ✔ DB_NAME   : " + DB_NAME);
            System.out.println("[BOOT] ✔ POOL_SIZE : " + POOL_SIZE);
            System.out.println("[BOOT] ✔ LOG_LEVEL : " + LOG_LEVEL);
            System.out.println("[BOOT] ✔ BASE_URL  : " + BASE_URL);
            System.out.println("[BOOT] Configuration loaded successfully!\n");

        } catch (Exception e) {
            // Static block mein exception handle kar sakte hain!
            throw new RuntimeException("Config loading failed: " + e.getMessage());
        }
    }

    static String getConnectionString() {
        return "jdbc:mysql://" + DB_HOST + ":" + DB_PORT + "/" + DB_NAME;
    }

    public static void main(String[] args) {
        System.out.println("[APP] Application starting...");
        System.out.println("[APP] Config loaded: " + configLoaded);
        System.out.println("[APP] Connection : " + AppConfig.getConnectionString());
        System.out.println("[APP] API Base   : " + AppConfig.BASE_URL);
        System.out.println("[APP] Pool size  : " + AppConfig.POOL_SIZE);
    }
}
▶ OUTPUT
[BOOT] Loading application configuration...
[BOOT] ✔ DB_HOST   : localhost
[BOOT] ✔ DB_PORT   : 3306
[BOOT] ✔ DB_NAME   : backend_app
[BOOT] ✔ POOL_SIZE : 10
[BOOT] ✔ LOG_LEVEL : INFO
[BOOT] ✔ BASE_URL  : https://api.myapp.com/v1
[BOOT] Configuration loaded successfully!

[APP] Application starting...
[APP] Config loaded: true
[APP] Connection : jdbc:mysql://localhost:3306/backend_app
[APP] API Base   : https://api.myapp.com/v1
[APP] Pool size  : 10
📁 Program 4 — Complete Lifecycle: Static Block vs Constructor P3.4
Static block, instance initializer, aur constructor — teeno ka execution order ek saath dekho.
class LifecycleDemo {

    static int staticVar = 0;
    int        instanceVar;
    static int objectNumber = 0;

    // 1. Static block — class load pe ONCE
    static {
        staticVar = 100;
        System.out.println("1️⃣  STATIC BLOCK runs ONCE | staticVar=" + staticVar);
    }

    // 2. Instance initializer block — har object ke liye (constructor se pehle)
    {
        objectNumber++;
        System.out.println("2️⃣  INSTANCE INIT BLOCK | object #" + objectNumber);
        instanceVar = staticVar + objectNumber;  // uses static var
    }

    // 3. Constructor — har object ke liye (instance block ke baad)
    LifecycleDemo(String name) {
        System.out.println("3️⃣  CONSTRUCTOR | " + name
                         + " | instanceVar=" + instanceVar + "\n");
    }

    public static void main(String[] args) {
        System.out.println("━━━ Creating Object 1 ━━━");
        LifecycleDemo o1 = new LifecycleDemo("First");

        System.out.println("━━━ Creating Object 2 ━━━");
        LifecycleDemo o2 = new LifecycleDemo("Second");

        System.out.println("━━━ Creating Object 3 ━━━");
        LifecycleDemo o3 = new LifecycleDemo("Third");

        System.out.println("━━━ Final State ━━━");
        System.out.println("staticVar   = " + staticVar);
        System.out.println("o1.instanceVar = " + o1.instanceVar);
        System.out.println("o2.instanceVar = " + o2.instanceVar);
        System.out.println("o3.instanceVar = " + o3.instanceVar);
    }
}
▶ OUTPUT
━━━ Creating Object 1 ━━━
1️⃣  STATIC BLOCK runs ONCE | staticVar=100
2️⃣  INSTANCE INIT BLOCK | object #1
3️⃣  CONSTRUCTOR | First | instanceVar=101

━━━ Creating Object 2 ━━━
2️⃣  INSTANCE INIT BLOCK | object #2
3️⃣  CONSTRUCTOR | Second | instanceVar=102

━━━ Creating Object 3 ━━━
2️⃣  INSTANCE INIT BLOCK | object #3
3️⃣  CONSTRUCTOR | Third | instanceVar=103

━━━ Final State ━━━
staticVar      = 100
o1.instanceVar = 101
o2.instanceVar = 102
o3.instanceVar = 103
📁 Program 5 — Lookup Table Initialization with Static Block P3.5
Static block se Maps aur lookup tables pre-populate karo — real backend mein commonly used pattern.
import java.util.*;

class CountryDatabase {

    // Static maps — once initialize, always available
    private static final Map<String, String> COUNTRY_CODES = new HashMap<>();
    private static final Map<String, String> CURRENCIES     = new HashMap<>();
    private static final Map<String, Integer> DIAL_CODES   = new HashMap<>();
    private static int entryCount = 0;

    // Static block: data load karo — database/file ki tarah
    static {
        System.out.println("[DB] Loading country database...");

        // Country code → Country name
        COUNTRY_CODES.put("IN", "India");
        COUNTRY_CODES.put("US", "United States");
        COUNTRY_CODES.put("GB", "United Kingdom");
        COUNTRY_CODES.put("JP", "Japan");
        COUNTRY_CODES.put("DE", "Germany");
        COUNTRY_CODES.put("AU", "Australia");

        // Country code → Currency
        CURRENCIES.put("IN", "INR - Indian Rupee");
        CURRENCIES.put("US", "USD - US Dollar");
        CURRENCIES.put("GB", "GBP - British Pound");
        CURRENCIES.put("JP", "JPY - Japanese Yen");
        CURRENCIES.put("DE", "EUR - Euro");
        CURRENCIES.put("AU", "AUD - Australian Dollar");

        // Country code → Dial code
        DIAL_CODES.put("IN", 91);  DIAL_CODES.put("US", 1);
        DIAL_CODES.put("GB", 44);  DIAL_CODES.put("JP", 81);
        DIAL_CODES.put("DE", 49);  DIAL_CODES.put("AU", 61);

        entryCount = COUNTRY_CODES.size();
        System.out.println("[DB] Loaded " + entryCount + " countries successfully!\n");
    }

    // Static lookup methods — no object needed!
    static String getCountry(String code)  { return COUNTRY_CODES.getOrDefault(code, "Unknown"); }
    static String getCurrency(String code) { return CURRENCIES.getOrDefault(code, "Unknown"); }
    static int    getDialCode(String code) { return DIAL_CODES.getOrDefault(code, 0); }

    static void lookup(String code) {
        System.out.printf("Code: %-4s | Country: %-20s | Currency: %-25s | Dial: +%d%n",
                code, getCountry(code), getCurrency(code), getDialCode(code));
    }

    public static void main(String[] args) {
        String[] codes = {"IN", "US", "GB", "JP", "DE", "AU", "XY"};
        System.out.println("Country Lookup Results:");
        System.out.println("─".repeat(75));
        for (String code : codes) lookup(code);
        System.out.println("\nTotal entries: " + entryCount);
    }
}
▶ OUTPUT
[DB] Loading country database...
[DB] Loaded 6 countries successfully!

Country Lookup Results:
───────────────────────────────────────────────────────────────────────────
Code: IN   | Country: India                | Currency: INR - Indian Rupee      | Dial: +91
Code: US   | Country: United States        | Currency: USD - US Dollar          | Dial: +1
Code: GB   | Country: United Kingdom       | Currency: GBP - British Pound      | Dial: +44
Code: JP   | Country: Japan                | Currency: JPY - Japanese Yen       | Dial: +81
Code: DE   | Country: Germany              | Currency: EUR - Euro               | Dial: +49
Code: AU   | Country: Australia            | Currency: AUD - Australian Dollar  | Dial: +61
Code: XY   | Country: Unknown              | Currency: Unknown                  | Dial: +0

Total entries: 6
🏗️

Topic 4 — Static Nested Class

Outer object ke bina nested class — Builder, Node, Helper patterns

📖 Theory: Static Nested Class Kya Hai?

Java mein ek class ke andar doosri class define kar sakte hain — ise nested class kehte hain. Nested classes 4 types ki hoti hain: Static Nested, Inner (non-static), Local, aur Anonymous. Aaj ka topic hai Static Nested Class.

Static Nested Class ke characteristics:

  • Independent existence: Outer class ke object ki zaroorat nahi — directly instantiate ho sakti hai
  • Access restriction: Outer class ke sirf static members access kar sakti hai (non-static instance members nahi)
  • Logically grouped: Outer class ke saath logically related hai isliye andar rakha, lekin tightly coupled nahi hai
  • No outer reference: Inner class ki tarah outer object ka hidden reference nahi hota — memory efficient

Inner Class (non-static) se fark: Inner class ke object banane ke liye pehle outer class ka object banana padta hai (outerObj.new Inner()). Static nested class mein aisa nahi — sirf new Outer.Nested() likhna hoga.

Real-world use cases: Builder pattern (Lombok @Builder ke andar), LinkedList Node, Tree Node, HTTP Request/Response models, API Response wrappers.

STATIC NESTED vs INNER CLASS — Comparison class Outer { int outerInstance = 10; // instance var static int outerStatic = 20; // static var // STATIC NESTED CLASS static class Nested { void show() { // outerInstance = ??? ← ERROR! no outer object reference System.out.println(outerStatic); // ✅ static only } } // INNER CLASS (non-static) class Inner { void show() { System.out.println(outerInstance); // ✅ has outer reference System.out.println(outerStatic); // ✅ also static } } } // CREATING OBJECTS: Outer.Nested n = new Outer.Nested(); // No Outer object needed ✅ Outer o = new Outer(); Outer.Inner i = o.new Inner(); // Outer object MUST exist ✅ // MEMORY: // Nested: independent — no hidden Outer reference // Inner: each Inner object holds reference to Outer — memory overhead
📁 Program 1 — Static Nested vs Inner Class Basics P4.1
Dono ka fundamental difference ek program mein — access rules aur object creation.
public class NestedClassDemo {

    private static int outerStatic   = 100;
    private int        outerInstance = 200;

    // ── STATIC NESTED CLASS ──
    static class StaticNested {
        int nestedVar = 50;

        void display() {
            System.out.println("StaticNested.display()");
            System.out.println("  outerStatic   = " + outerStatic);   // ✅ static access
            // outerInstance = ??? ← COMPILE ERROR
            System.out.println("  nestedVar     = " + nestedVar);
        }

        void compute(int x) {
            System.out.println("  outerStatic * x = " + (outerStatic * x));
        }
    }

    // ── INNER CLASS (non-static) ──
    class Inner {
        void display() {
            System.out.println("Inner.display()");
            System.out.println("  outerStatic   = " + outerStatic);   // ✅
            System.out.println("  outerInstance = " + outerInstance); // ✅ both access
        }
    }

    public static void main(String[] args) {
        System.out.println("── Static Nested (no outer object needed) ──");
        NestedClassDemo.StaticNested nested = new NestedClassDemo.StaticNested();
        nested.display();
        nested.compute(5);

        System.out.println("\n── Inner Class (outer object required) ──");
        NestedClassDemo outer = new NestedClassDemo();
        NestedClassDemo.Inner inner = outer.new Inner();
        inner.display();

        System.out.println("\n── Summary ──");
        System.out.println("Static Nested: new Outer.Nested()       — independent");
        System.out.println("Inner Class  : outerObj.new Inner()     — needs outer");
    }
}
▶ OUTPUT
── Static Nested (no outer object needed) ──
StaticNested.display()
  outerStatic   = 100
  nestedVar     = 50
  outerStatic * x = 500

── Inner Class (outer object required) ──
Inner.display()
  outerStatic   = 100
  outerInstance = 200

── Summary ──
Static Nested: new Outer.Nested()       — independent
Inner Class  : outerObj.new Inner()     — needs outer
📁 Program 2 — Builder Pattern (Most Common Use of Static Nested) P4.2
Builder Pattern — complex objects banana fluently. Spring, Hibernate, Lombok sab isi pattern pe hain.
class Product {

    // All fields — private, set only via Builder
    private final String name;
    private final String category;
    private final double price;
    private final int    quantity;
    private final String sku;
    private final boolean inStock;

    // Private constructor — sirf Builder banayega
    private Product(Builder b) {
        this.name     = b.name;
        this.category = b.category;
        this.price    = b.price;
        this.quantity = b.quantity;
        this.sku      = b.sku;
        this.inStock  = b.quantity > 0;
    }

    // ★ STATIC NESTED BUILDER CLASS ★
    static class Builder {
        // Required
        private String name;
        // Optional (with defaults)
        private String category = "General";
        private double price    = 0.0;
        private int    quantity = 0;
        private String sku      = "SKU-" + System.currentTimeMillis() % 1000;

        Builder(String name) { this.name = name; }

        // Fluent setters — each returns Builder for chaining
        Builder category(String c) { this.category = c; return this; }
        Builder price(double p)    { this.price    = p; return this; }
        Builder quantity(int q)    { this.quantity = q; return this; }
        Builder sku(String s)      { this.sku      = s; return this; }

        // Validation before building
        Product build() {
            if (name == null || name.isEmpty())
                throw new IllegalStateException("Product name required!");
            if (price < 0)
                throw new IllegalStateException("Price cannot be negative!");
            return new Product(this);
        }
    }

    void display() {
        System.out.println("━━━ " + name + " ━━━");
        System.out.println("  SKU      : " + sku);
        System.out.println("  Category : " + category);
        System.out.printf ("  Price    : ₹%.2f%n", price);
        System.out.println("  Quantity : " + quantity);
        System.out.println("  In Stock : " + (inStock ? "✔ Yes" : "✘ Out of Stock"));
    }

    public static void main(String[] args) {
        // Fluent builder — readable, no constructor hell!
        Product p1 = new Product.Builder("MacBook Pro")
                        .category("Electronics")
                        .price(125000)
                        .quantity(15)
                        .sku("ELEC-001")
                        .build();

        Product p2 = new Product.Builder("Java Programming Book")
                        .category("Books")
                        .price(599)
                        .quantity(0)   // out of stock
                        .sku("BOOK-042")
                        .build();

        // Minimal — just name (optional fields default pe)
        Product p3 = new Product.Builder("Sample Item").build();

        p1.display(); System.out.println();
        p2.display(); System.out.println();
        p3.display();
    }
}
▶ OUTPUT
━━━ MacBook Pro ━━━
  SKU      : ELEC-001
  Category : Electronics
  Price    : ₹125000.00
  Quantity : 15
  In Stock : ✔ Yes

━━━ Java Programming Book ━━━
  SKU      : BOOK-042
  Category : Books
  Price    : ₹599.00
  Quantity : 0
  In Stock : ✘ Out of Stock

━━━ Sample Item ━━━
  SKU      : SKU-892
  Category : General
  Price    : ₹0.00
  Quantity : 0
  In Stock : ✘ Out of Stock
📁 Program 3 — Linked List Node (Data Structure) P4.3
Static nested Node class — outer object ki zaroorat nahi. Java ki LinkedList internals isi tarah kaam karte hain.
public class MyLinkedList {

    // ★ Static Nested Node — outer object nahi chahiye
    static class Node {
        int  data;
        Node next;
        Node(int data) { this.data = data; this.next = null; }
    }

    private Node head = null;
    private int  size = 0;

    void addFirst(int val) {
        Node n = new Node(val);  // No outer object — just new Node()
        n.next = head;
        head   = n;
        size++;
    }

    void addLast(int val) {
        Node n = new Node(val);
        if (head == null) { head = n; size++; return; }
        Node cur = head;
        while (cur.next != null) cur = cur.next;
        cur.next = n;
        size++;
    }

    boolean removeFirst() {
        if (head == null) return false;
        head = head.next;
        size--;
        return true;
    }

    int sum() {
        int total = 0;
        Node cur = head;
        while (cur != null) { total += cur.data; cur = cur.next; }
        return total;
    }

    void reverse() {
        Node prev = null, curr = head, next;
        while (curr != null) {
            next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        head = prev;
    }

    void print(String label) {
        System.out.print(label + ": ");
        Node cur = head;
        while (cur != null) {
            System.out.print(cur.data + (cur.next != null ? " → " : ""));
            cur = cur.next;
        }
        System.out.println(" | size=" + size + " | sum=" + sum());
    }

    public static void main(String[] args) {
        MyLinkedList list = new MyLinkedList();
        list.addLast(10); list.addLast(20); list.addLast(30);
        list.addFirst(5); list.addLast(40);
        list.print("Original ");

        list.reverse();
        list.print("Reversed ");

        list.removeFirst();
        list.print("After del");

        // Node can be used standalone — no MyLinkedList needed!
        MyLinkedList.Node standalone = new MyLinkedList.Node(999);
        System.out.println("\nStandalone node: " + standalone.data);
    }
}
▶ OUTPUT
Original : 5 → 10 → 20 → 30 → 40 | size=5 | sum=105
Reversed : 40 → 30 → 20 → 10 → 5 | size=5 | sum=105
After del: 30 → 20 → 10 → 5 | size=4 | sum=65

Standalone node: 999
📁 Program 4 — API Response Wrapper (Backend Pattern) P4.4
REST API response class — static nested classes se structured responses banao. Real Spring Boot projects mein aise patterns use hote hain.
public class ApiResponse {

    private int    status;
    private String message;
    private Object data;
    private boolean success;
    private long   timestamp;

    private ApiResponse(int status, String message, Object data, boolean success) {
        this.status    = status;
        this.message   = message;
        this.data      = data;
        this.success   = success;
        this.timestamp = System.currentTimeMillis();
    }

    // Static factory methods
    static ApiResponse ok(Object data)            { return new ApiResponse(200, "Success", data, true); }
    static ApiResponse created(Object data)       { return new ApiResponse(201, "Created", data, true); }
    static ApiResponse notFound(String msg)       { return new ApiResponse(404, msg, null, false); }
    static ApiResponse badRequest(String msg)     { return new ApiResponse(400, msg, null, false); }
    static ApiResponse serverError(String msg)    { return new ApiResponse(500, msg, null, false); }

    // ★ Static Nested DTOs ★
    static class UserDTO {
        String id, name, email, role;
        UserDTO(String id, String name, String email, String role) {
            this.id=id; this.name=name; this.email=email; this.role=role;
        }
        public String toString() {
            return "{id:"+id+", name:"+name+", email:"+email+", role:"+role+"}";
        }
    }

    static class PagedResult {
        Object[] items;
        int page, totalPages, totalCount;
        PagedResult(Object[] items, int page, int totalPages, int total) {
            this.items=items; this.page=page; this.totalPages=totalPages; this.totalCount=total;
        }
        public String toString() {
            return "{page:"+page+"/"+totalPages+", total:"+totalCount+", items:"+items.length+"}";
        }
    }

    void print() {
        System.out.println("{");
        System.out.println("  status  : " + status);
        System.out.println("  success : " + success);
        System.out.println("  message : \"" + message + "\"");
        System.out.println("  data    : " + data);
        System.out.println("}");
    }

    public static void main(String[] args) {
        ApiResponse.UserDTO user = new ApiResponse.UserDTO("U001","Rahul","rahul@g.com","ADMIN");

        System.out.println("GET /api/users/U001");
        ApiResponse.ok(user).print();

        System.out.println("\nPOST /api/users");
        ApiResponse.created(user).print();

        System.out.println("\nGET /api/users/XYZ");
        ApiResponse.notFound("User not found with id: XYZ").print();

        ApiResponse.UserDTO[] users = {
            new ApiResponse.UserDTO("U001","Rahul","r@g.com","ADMIN"),
            new ApiResponse.UserDTO("U002","Priya","p@g.com","USER")
        };
        ApiResponse.PagedResult paged = new ApiResponse.PagedResult(users, 1, 5, 47);
        System.out.println("\nGET /api/users?page=1");
        ApiResponse.ok(paged).print();
    }
}
▶ OUTPUT
GET /api/users/U001
{
  status  : 200
  success : true
  message : "Success"
  data    : {id:U001, name:Rahul, email:rahul@g.com, role:ADMIN}
}

POST /api/users
{
  status  : 201
  success : true
  message : "Created"
  data    : {id:U001, name:Rahul, email:rahul@g.com, role:ADMIN}
}

GET /api/users/XYZ
{
  status  : 404
  success : false
  message : "User not found with id: XYZ"
  data    : null
}

GET /api/users?page=1
{
  status  : 200
  success : true
  message : "Success"
  data    : {page:1/5, total:47, items:2}
}
📥

Topic 5 — Static Import

Class name likhne ki zaroorat nahi — directly static members use karo

📖 Theory: Static Import Kya Hai?

Static import Java 5 mein introduce hua. Isse aap kisi class ke static members (variables aur methods) ko directly use kar sakte ho — class name likhne ki zaroorat nahi padti.

Syntax:

  • import static java.lang.Math.PI; — sirf PI import
  • import static java.lang.Math.*; — Math ke sab static members
  • import static java.lang.System.out; — System.out ko out se use karo

Kab use karein:

  • Scientific calculations jahan Math. baar baar likhna repetitive lage
  • JUnit testing mein — import static org.junit.Assert.*;
  • Constants heavy code — AppConstants.MAX baar baar likhne ki jagah

Kab avoid karein:

  • Jab do alag classes mein same naam ka static member ho — ambiguity aayegi
  • Jab code padh kar samajh na aaye ki method kahan se aaya — readability hurt hoti hai
  • Overuse mat karo — Math.sqrt() zyada readable hai sirf sqrt() se
📁 Program 1 — Math Static Import: Before vs After P5.1
Math class ke static methods without aur with static import — fark dekho.
import static java.lang.Math.*;
import static java.lang.System.out;

public class StaticImportMath {

    // Custom methods using static imported names directly
    static double circleArea(double r)         { return PI * r * r; }
    static double hypotenuse(double a, double b){ return sqrt(a*a + b*b); }
    static double degToRad(double d)           { return d * PI / 180.0; }

    public static void main(String[] args) {
        out.println("── Math Constants ──");
        out.println("PI  = " + PI);   // Math.PI
        out.println("E   = " + E);    // Math.E

        out.println("\n── Common Operations ──");
        out.println("sqrt(144)     = " + sqrt(144));     // Math.sqrt
        out.println("pow(2,10)     = " + pow(2, 10));    // Math.pow
        out.println("abs(-99)      = " + abs(-99));      // Math.abs
        out.println("ceil(4.1)     = " + ceil(4.1));     // Math.ceil
        out.println("floor(4.9)    = " + floor(4.9));    // Math.floor
        out.println("round(4.5)    = " + round(4.5));    // Math.round
        out.println("max(17,42)    = " + max(17, 42));   // Math.max
        out.println("log(E)        = " + log(E));        // Math.log

        out.println("\n── Geometry ──");
        out.printf("circleArea(r=5)     = %.4f%n", circleArea(5));
        out.printf("hypotenuse(3,4)     = %.1f%n",  hypotenuse(3, 4));

        out.println("\n── Trigonometry ──");
        double[] degs = {0, 30, 45, 60, 90};
        for (double d : degs) {
            out.printf("sin(%2.0f°)=%.4f  cos(%2.0f°)=%.4f%n",
                        d, sin(degToRad(d)), d, cos(degToRad(d)));
        }
    }
}
▶ OUTPUT
── Math Constants ──
PI  = 3.141592653589793
E   = 2.718281828459045

── Common Operations ──
sqrt(144)     = 12.0
pow(2,10)     = 1024.0
abs(-99)      = 99
ceil(4.1)     = 5.0
floor(4.9)    = 4.0
round(4.5)    = 5
max(17,42)    = 42
log(E)        = 1.0

── Geometry ──
circleArea(r=5)     = 78.5398
hypotenuse(3,4)     = 5.0

── Trigonometry ──
sin( 0°)=0.0000  cos( 0°)=1.0000
sin(30°)=0.5000  cos(30°)=0.8660
sin(45°)=0.7071  cos(45°)=0.7071
sin(60°)=0.8660  cos(60°)=0.5000
sin(90°)=1.0000  cos(90°)=0.0000
📁 Program 2 — Arrays Static Import P5.2
Arrays class ke static methods import karo — sorting, copying, filling clean code se.
import static java.lang.System.out;
import static java.lang.System.err;
import static java.util.Arrays.sort;
import static java.util.Arrays.fill;
import static java.util.Arrays.copyOf;
import static java.util.Arrays.copyOfRange;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.toString;

public class StaticImportArrays {

    public static void main(String[] args) {
        int[] arr = {5, 2, 8, 1, 9, 3, 7, 4, 6};

        out.println("Original : " + toString(arr));   // Arrays.toString

        sort(arr);   // Arrays.sort
        out.println("Sorted   : " + toString(arr));

        // binarySearch — array must be sorted
        int idx = binarySearch(arr, 7);   // Arrays.binarySearch
        out.println("Index of 7: " + idx);

        // copyOf — first n elements
        int[] first5 = copyOf(arr, 5);    // Arrays.copyOf
        out.println("First 5  : " + toString(first5));

        // copyOfRange — slice
        int[] mid = copyOfRange(arr, 2, 6); // Arrays.copyOfRange
        out.println("Index 2-5: " + toString(mid));

        // fill — all same value
        int[] zeros = new int[5];
        fill(zeros, 0);   // Arrays.fill
        out.println("Filled 0s: " + toString(zeros));

        fill(zeros, 99);
        out.println("Filled 99: " + toString(zeros));

        // err — System.err (stderr stream)
        err.println("[ERR] This is error stream output");
    }
}
▶ OUTPUT
Original : [5, 2, 8, 1, 9, 3, 7, 4, 6]
Sorted   : [1, 2, 3, 4, 5, 6, 7, 8, 9]
Index of 7: 6
First 5  : [1, 2, 3, 4, 5]
Index 2-5: [3, 4, 5, 6]
Filled 0s: [0, 0, 0, 0, 0]
Filled 99: [99, 99, 99, 99, 99]
[ERR] This is error stream output
📁 Program 3 — Custom Constants: Static Import P5.3
Apni constants class ke static members import karo — AppConstants baar baar likhne ki zaroorat nahi.
// Constants class — same package mein ho toh import karo
class HttpCode {
    static final int OK           = 200;
    static final int CREATED      = 201;
    static final int NO_CONTENT   = 204;
    static final int BAD_REQUEST  = 400;
    static final int UNAUTHORIZED = 401;
    static final int NOT_FOUND    = 404;
    static final int SERVER_ERROR = 500;

    static String describe(int code) {
        switch(code) {
            case 200: return "OK";
            case 201: return "Created";
            case 204: return "No Content";
            case 400: return "Bad Request";
            case 401: return "Unauthorized";
            case 404: return "Not Found";
            case 500: return "Internal Server Error";
            default:  return "Unknown";
        }
    }
}

// Normally: import static HttpCode.*;
// (In single file, we use HttpCode. directly — same concept)
public class StaticImportConstants {

    public static void main(String[] args) {
        // Without static import:
        System.out.println(HttpCode.OK + " - " + HttpCode.describe(HttpCode.OK));
        System.out.println(HttpCode.NOT_FOUND + " - " + HttpCode.describe(HttpCode.NOT_FOUND));

        // Concept: agar alag file hoti aur import static karte:
        //   import static HttpCode.*;
        //   System.out.println(OK + " - " + describe(OK));   ← clean!
        //   System.out.println(NOT_FOUND + " - " + describe(NOT_FOUND));

        System.out.println("\n── All Status Codes ──");
        int[] codes = {200, 201, 204, 400, 401, 404, 500};
        for (int code : codes) {
            System.out.printf("  %d — %s%n", code, HttpCode.describe(code));
        }

        // Practical: response handling
        int responseCode = 404;
        if (responseCode == HttpCode.OK) {
            System.out.println("Success!");
        } else if (responseCode == HttpCode.NOT_FOUND) {
            System.out.println("Resource not found!");
        } else if (responseCode >= HttpCode.SERVER_ERROR) {
            System.out.println("Server error!");
        }
    }
}
▶ OUTPUT
200 - OK
404 - Not Found

── All Status Codes ──
  200 — OK
  201 — Created
  204 — No Content
  400 — Bad Request
  401 — Unauthorized
  404 — Not Found
  500 — Internal Server Error

Resource not found!
📁 Program 4 — JUnit-Style Testing with Static Import P5.4
Static import ka sabse common real use — JUnit mein import static org.junit.Assert.* karte hain. Iska simulation dekho.
import static java.lang.Math.*;
import static java.lang.System.out;

// JUnit-style assertions (simplified version)
class Assert {
    static int passed = 0, failed = 0;

    static void assertEquals(Object expected, Object actual, String test) {
        if (expected.equals(actual)) {
            out.println("  ✔ PASS: " + test); passed++;
        } else {
            out.println("  ✘ FAIL: " + test + " | Expected=" + expected + " Got=" + actual);
            failed++;
        }
    }
    static void assertTrue(boolean cond, String test) {
        if (cond) { out.println("  ✔ PASS: " + test); passed++; }
        else      { out.println("  ✘ FAIL: " + test); failed++; }
    }
    static void assertFalse(boolean cond, String test) {
        assertTrue(!cond, "NOT: " + test);
    }
    static void summary() {
        out.println("\n  Results: " + passed + " passed, " + failed + " failed");
    }
}

// Class under test
class Calculator {
    static int    add(int a, int b)      { return a + b; }
    static int    multiply(int a, int b) { return a * b; }
    static double squareRoot(double n)   { return Math.sqrt(n); }
    static boolean isEven(int n)         { return n % 2 == 0; }
    static int    clamp(int v, int lo, int hi) { return Math.max(lo, Math.min(hi, v)); }
}

// Normally: import static Assert.*;  and  import static Calculator.*;
public class StaticImportTesting {

    public static void main(String[] args) {
        out.println("═══ Running Calculator Tests ═══\n");

        // Addition tests
        out.println("── Addition ──");
        Assert.assertEquals(5,  Calculator.add(2, 3),    "add(2,3) = 5");
        Assert.assertEquals(0,  Calculator.add(-5, 5),   "add(-5,5) = 0");
        Assert.assertEquals(-8, Calculator.add(-3, -5),  "add(-3,-5) = -8");

        // Multiply tests
        out.println("\n── Multiplication ──");
        Assert.assertEquals(6,  Calculator.multiply(2, 3),  "multiply(2,3) = 6");
        Assert.assertEquals(0,  Calculator.multiply(0, 99), "multiply(0,99) = 0");

        // Square root tests
        out.println("\n── Square Root ──");
        Assert.assertTrue(abs(Calculator.squareRoot(25) - 5.0) < 0.001, "sqrt(25) ≈ 5.0");
        Assert.assertTrue(abs(Calculator.squareRoot(2) - sqrt(2)) < 0.001, "sqrt(2) correct");

        // Even tests
        out.println("\n── isEven ──");
        Assert.assertTrue (Calculator.isEven(4),  "4 is even");
        Assert.assertFalse(Calculator.isEven(7),  "7 is odd");
        Assert.assertTrue (Calculator.isEven(0),  "0 is even");

        // Clamp tests
        out.println("\n── Clamp ──");
        Assert.assertEquals(100, Calculator.clamp(150, 0, 100), "clamp(150,0,100)=100");
        Assert.assertEquals(0,   Calculator.clamp(-50, 0, 100), "clamp(-50,0,100)=0");
        Assert.assertEquals(50,  Calculator.clamp(50, 0, 100),  "clamp(50,0,100)=50");

        Assert.summary();
    }
}
▶ OUTPUT
═══ Running Calculator Tests ═══

── Addition ──
  ✔ PASS: add(2,3) = 5
  ✔ PASS: add(-5,5) = 0
  ✔ PASS: add(-3,-5) = -8

── Multiplication ──
  ✔ PASS: multiply(2,3) = 6
  ✔ PASS: multiply(0,99) = 0

── Square Root ──
  ✔ PASS: sqrt(25) ≈ 5.0
  ✔ PASS: sqrt(2) correct

── isEven ──
  ✔ PASS: 4 is even
  ✔ PASS: NOT: 7 is odd
  ✔ PASS: 0 is even

── Clamp ──
  ✔ PASS: clamp(150,0,100)=100
  ✔ PASS: clamp(-50,0,100)=0
  ✔ PASS: clamp(50,0,100)=50

  Results: 13 passed, 0 failed
🧬

Topic 6 — Static in Inheritance

Method Hiding vs Overriding — compile-time vs runtime binding

📖 Theory: Static aur Inheritance

Jab inheritance mein static methods aur variables ka use hota hai, tab ek important concept aata hai: Method Hiding (jo Method Overriding se bilkul alag hai).

Method Overriding (Instance method): Jab child class mein parent ka instance method redefine kiya jaata hai, toh yeh true polymorphism hai. Runtime mein JVM actual object ka type dekhta hai aur child ka method call karta hai — chahe reference parent type ka kyon na ho. Yeh runtime binding hai.

Method Hiding (Static method): Jab child class mein parent ka static method redefine kiya jaata hai, toh yeh override nahi hota — sirf "hide" hota hai. Reference variable ka type (compile-time) decide karta hai kaunsa method call hoga — actual object type nahi. Yeh compile-time binding hai.

Key rule: Static methods are resolved at compile time based on the reference type, NOT the actual object type. Isliye static methods ke saath polymorphism kaam nahi karta.

METHOD HIDING vs METHOD OVERRIDING class Parent { static void staticMethod() { print("Parent Static"); } // static void instanceMethod() { print("Parent Instance"); } // instance } class Child extends Parent { static void staticMethod() { print("Child Static"); } // HIDING void instanceMethod() { print("Child Instance"); } // OVERRIDING } Parent ref = new Child(); // Child object, Parent reference ref.staticMethod(); → "Parent Static" ← compile-time! reference=Parent ref.instanceMethod(); → "Child Instance" ← runtime! object=Child Parent.staticMethod(); → "Parent Static" ← direct class call Child.staticMethod(); → "Child Static" ← direct class call ══════════════════════════════════════════════════════ COMPILE-TIME RUNTIME Static: reference type decides — Instance: — actual object decides ══════════════════════════════════════════════════════ @Override on static → COMPILER WARNING (not true override)
📁 Program 1 — Method Hiding vs Method Overriding P6.1
Static method HIDE hota hai, instance method OVERRIDE hota hai — dono ka fark ek program mein.
class Animal {
    static String type = "Animal";

    // Static method — child mein redefine karo: HIDING (not override)
    static void staticSound() {
        System.out.println("Animal.staticSound() — reference type decides");
    }

    // Instance method — child mein redefine karo: TRUE OVERRIDE
    void instanceSound() {
        System.out.println("Animal.instanceSound() — actual object decides");
    }

    void describe() {
        System.out.println("I am a " + type + " [static variable: compile-time]");
    }
}

class Dog extends Animal {
    static String type = "Dog";  // variable HIDING

    // Method HIDING — NOT override
    static void staticSound() {
        System.out.println("Dog.staticSound() — woof!");
    }

    // TRUE Override — runtime polymorphism
    @Override
    void instanceSound() {
        System.out.println("Dog.instanceSound() — WOOF WOOF!");
    }
}

public class InheritanceStatic1 {
    public static void main(String[] args) {

        System.out.println("── ref = new Dog() [Animal reference] ──");
        Animal ref = new Dog();  // Dog object, Animal reference

        // Static: compile-time → Animal's method (reference type = Animal)
        ref.staticSound();      // Animal's!
        Animal.staticSound();   // Animal's
        Dog.staticSound();      // Dog's

        System.out.println();

        // Instance: runtime → Dog's method (actual object = Dog)
        ref.instanceSound();    // Dog's! (polymorphism)

        System.out.println("\n── Variable Hiding ──");
        System.out.println("ref.type    = " + ref.type);    // Animal (compile-time)
        System.out.println("Animal.type = " + Animal.type); // Animal
        System.out.println("Dog.type    = " + Dog.type);    // Dog

        System.out.println("\n── With actual Dog reference ──");
        Dog dog = new Dog();
        dog.staticSound();    // Dog's (reference = Dog)
        dog.instanceSound();  // Dog's
    }
}
▶ OUTPUT
── ref = new Dog() [Animal reference] ──
Animal.staticSound() — reference type decides
Animal.staticSound() — reference type decides
Dog.staticSound() — woof!

Dog.instanceSound() — WOOF WOOF!

── Variable Hiding ──
ref.type    = Animal
Animal.type = Animal
Dog.type    = Dog

── With actual Dog reference ──
Dog.staticSound() — woof!
Dog.instanceSound() — WOOF WOOF!
📁 Program 2 — Static Members in Inheritance: Counter Example P6.2
Parent ki static variable child classes bhi share karti hain — counter accumulate hota hai across all subclasses.
class Shape {

    // Shared static — sabhi shapes count
    static int totalShapes = 0;
    static String category = "2D Shape";

    String color;

    Shape(String color) {
        this.color = color;
        totalShapes++;  // har shape — parent + child dono count
    }

    // Static method — child access kar sakti hai
    static void showStats() {
        System.out.println("Category: " + category +
                           " | Total shapes: " + totalShapes);
    }

    double area() { return 0; }  // override karo
}

class Circle extends Shape {
    double radius;
    static int circleCount = 0;

    Circle(String color, double radius) {
        super(color);
        this.radius = radius;
        circleCount++;
    }

    @Override
    double area() { return Math.PI * radius * radius; }

    void info() {
        System.out.printf("Circle  | color=%s | r=%.1f | area=%.2f%n",
                           color, radius, area());
    }
}

class Rectangle extends Shape {
    double w, h;
    static int rectCount = 0;

    Rectangle(String color, double w, double h) {
        super(color);
        this.w = w; this.h = h;
        rectCount++;
    }

    @Override
    double area() { return w * h; }

    void info() {
        System.out.printf("Rect    | color=%s | %gx%g | area=%.2f%n",
                           color, w, h, area());
    }
}

public class InheritanceStatic2 {
    public static void main(String[] args) {
        Circle c1 = new Circle("Red", 5);
        Circle c2 = new Circle("Blue", 3);
        Rectangle r1 = new Rectangle("Green", 4, 6);
        Rectangle r2 = new Rectangle("Yellow", 10, 2);
        Rectangle r3 = new Rectangle("White", 7, 7);

        c1.info(); c2.info(); r1.info(); r2.info(); r3.info();

        System.out.println();
        Shape.showStats();                // parent static method
        Circle.showStats();               // same method via child — same result!
        System.out.println("Circles   : " + Circle.circleCount);
        System.out.println("Rectangles: " + Rectangle.rectCount);
        System.out.println("category  : " + Shape.category);
        System.out.println("          = " + Circle.category);   // inherited!
    }
}
▶ OUTPUT
Circle  | color=Red    | r=5.0 | area=78.54
Circle  | color=Blue   | r=3.0 | area=28.27
Rect    | color=Green  | 4.0x6.0 | area=24.00
Rect    | color=Yellow | 10x2.0  | area=20.00
Rect    | color=White  | 7.0x7.0 | area=49.00

Category: 2D Shape | Total shapes: 5
Category: 2D Shape | Total shapes: 5
Circles   : 2
Rectangles: 3
category  : 2D Shape
           = 2D Shape
📁 Program 3 — Inheritance Execution Order: Parent+Child P6.3
Inheritance mein static blocks aur constructors ka execution order — interview mein bahut poochha jaata hai!
class GrandParent {
    static { System.out.println("1. GrandParent STATIC BLOCK"); }
    GrandParent() { System.out.println("4. GrandParent CONSTRUCTOR\n"); }
}

class Parent extends GrandParent {
    static { System.out.println("2. Parent STATIC BLOCK"); }
    Parent() {
        // super() implicit — GrandParent constructor call
        System.out.println("5. Parent CONSTRUCTOR");
    }
}

class Child extends Parent {
    static { System.out.println("3. Child STATIC BLOCK"); }
    Child() {
        // super() implicit — Parent constructor call
        System.out.println("6. Child CONSTRUCTOR");
    }
}

public class InheritanceOrder {
    public static void main(String[] args) {
        System.out.println("=== First Object ===");
        Child c1 = new Child();

        System.out.println("=== Second Object ===");
        Child c2 = new Child();  // static blocks skip honge!

        System.out.println("=== Third Object ===");
        Child c3 = new Child();

        System.out.println("\nOrder Summary:");
        System.out.println("  Static: GrandParent → Parent → Child  (each once)");
        System.out.println("  Constructor: GrandParent → Parent → Child  (each time)");
    }
}
▶ OUTPUT
=== First Object ===
1. GrandParent STATIC BLOCK
2. Parent STATIC BLOCK
3. Child STATIC BLOCK
4. GrandParent CONSTRUCTOR

5. Parent CONSTRUCTOR
6. Child CONSTRUCTOR

=== Second Object ===
4. GrandParent CONSTRUCTOR

5. Parent CONSTRUCTOR
6. Child CONSTRUCTOR

=== Third Object ===
4. GrandParent CONSTRUCTOR

5. Parent CONSTRUCTOR
6. Child CONSTRUCTOR

Order Summary:
  Static: GrandParent → Parent → Child  (each once)
  Constructor: GrandParent → Parent → Child  (each time)
📁 Program 4 — Interface Static Methods (Java 8+) P6.4
Java 8 se interfaces mein static methods allowed hain — override nahi hote, sirf interface name se call hote hain.
interface Printable {
    // Abstract method — implement karna zaroori
    void print();

    // Static method — Java 8+ | override nahi hota
    static void printHeader(String title) {
        System.out.println("═".repeat(40));
        System.out.println("  " + title.toUpperCase());
        System.out.println("═".repeat(40));
    }

    // Default method — override kar sakte ho
    default void printWithBorder() {
        System.out.println("┌" + "─".repeat(38) + "┐");
        System.out.print("│ ");
        print();
        System.out.println("└" + "─".repeat(38) + "┘");
    }
}

interface Validatable {
    boolean validate();

    // Static factory — interface mein
    static Validatable of(String value) {
        return () -> value != null && !value.trim().isEmpty();
    }

    static Validatable emailValidator() {
        return () -> false; // placeholder
    }
}

class Report implements Printable {
    String title, content;

    Report(String title, String content) {
        this.title = title; this.content = content;
    }

    @Override
    public void print() {
        System.out.println("Report: " + title + " — " + content);
    }

    // Note: cannot override Printable.printHeader() — it's static!
}

public class InterfaceStaticMethod {

    public static void main(String[] args) {
        // Interface static method — only via interface name
        Printable.printHeader("Sales Report Q4 2024");

        Report r1 = new Report("Revenue", "₹12.5 Lakhs");
        Report r2 = new Report("Expenses", "₹8.2 Lakhs");

        r1.print();
        r1.printWithBorder();
        r2.printWithBorder();

        Printable.printHeader("Validation Demo");

        // Interface static factory
        Validatable v1 = Validatable.of("Hello World");
        Validatable v2 = Validatable.of("   ");
        Validatable v3 = Validatable.of(null);

        System.out.println("'Hello World' valid? " + v1.validate());  // true
        System.out.println("'   '         valid? " + v2.validate());  // false
        System.out.println("null          valid? " + v3.validate());  // false

        // Printable.printHeader cannot be called via Report object!
        // r1.printHeader("test"); ← COMPILE ERROR
        // Must use: Printable.printHeader("test");
    }
}
▶ OUTPUT
════════════════════════════════════════
  SALES REPORT Q4 2024
════════════════════════════════════════
Report: Revenue — ₹12.5 Lakhs
┌──────────────────────────────────────┐
│ Report: Revenue — ₹12.5 Lakhs
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│ Report: Expenses — ₹8.2 Lakhs
└──────────────────────────────────────┘
════════════════════════════════════════
  VALIDATION DEMO
════════════════════════════════════════
'Hello World' valid? true
'   '         valid? false
null          valid? false
⚠️

Topic 7 — Common Mistakes & Interview Questions

Jo galtiyan sabse zyada hoti hain — aur interview mein jo poochha jaata hai

📖 Theory: Common Static Mistakes

Static keyword ke saath kuch galtiyan bahut commonly hoti hain — ye compile errors ya unexpected runtime behavior cause karte hain. Teen sabse common mistakes:

  • Mistake 1 — Static method mein instance member: Static context mein instance variable ya method directly access karna. Fix: object create karo.
  • Mistake 2 — Override vs Hiding confusion: Static method ko @Override se mark karna — compiler warning deta hai. Static methods override nahi hote.
  • Mistake 3 — this keyword in static: Static method mein this likhna — compile error. this ka matlab hai "current object" — static context mein koi object nahi hota.
📁 Program 1 — Mistake: Instance Access in Static P7.1
Static method mein instance variable/method access — common compile error aur uska fix.
public class StaticMistake1 {

    int   instanceVar = 10;   // instance variable
    static int staticVar = 20; // static variable

    // ❌ YEH GALAT HAI — compile error aata hai:
    /*
    static void badMethod() {
        System.out.println(instanceVar);  // ERROR: non-static field
        show();                           // ERROR: non-static method
        this.instanceVar = 5;             // ERROR: 'this' not allowed
    }
    */

    // ✅ YEH SAHI HAI — static method, static access only
    static void correctStaticMethod() {
        System.out.println("staticVar = " + staticVar);  // ✅ static → static

        // Instance chahiye toh: pehle object banao
        StaticMistake1 obj = new StaticMistake1();
        System.out.println("instanceVar via obj = " + obj.instanceVar);  // ✅
        obj.show();  // ✅ object se instance method call
    }

    // ✅ Instance method — both access kar sakta hai
    void show() {
        System.out.println("show() | instanceVar=" + instanceVar
                         + " | staticVar=" + staticVar);  // ✅ dono
        correctStaticMethod();  // instance → static ✅
    }

    public static void main(String[] args) {
        System.out.println("── From static main ──");
        correctStaticMethod();

        System.out.println("\n── Via object ──");
        StaticMistake1 s = new StaticMistake1();
        s.show();
    }
}
▶ OUTPUT
── From static main ──
staticVar = 20
instanceVar via obj = 10
show() | instanceVar=10 | staticVar=20
staticVar = 20
instanceVar via obj = 10

── Via object ──
show() | instanceVar=10 | staticVar=20
staticVar = 20
instanceVar via obj = 10
📁 Program 2 — Interview: What is printed? (Tricky Questions) P7.2
Classic interview questions — static variable sharing, hiding, aur execution order ke tricky output predict karo.
public class InterviewQ {

    // Q1: Static variable sharing across objects
    static void q1() {
        System.out.println("Q1: Static variable sharing");
        class Box {
            static int count = 0;
            int id;
            Box() { count++; id = count; }
        }
        Box b1 = new Box();
        Box b2 = new Box();
        Box b3 = new Box();
        // What prints?
        System.out.println(b1.count); // 3 (not 1!)
        System.out.println(b2.count); // 3 (same memory)
        System.out.println(b3.id);    // 3
    }

    // Q2: Static method hiding
    static void q2() {
        System.out.println("\nQ2: Method Hiding");
        class Base {
            static void greet() { System.out.println("Base"); }
        }
        class Derived extends Base {
            static void greet() { System.out.println("Derived"); }
        }
        Base ref = new Derived();
        ref.greet();      // Base (compile-time! NOT Derived)
        Derived.greet();  // Derived
    }

    // Q3: Static variable vs local variable
    static void q3() {
        System.out.println("\nQ3: Static vs local scope");
        class Counter {
            static int s = 0;
            void inc() { s++; int local = s; System.out.println("s=" + s + " local=" + local); }
        }
        Counter c1 = new Counter();
        Counter c2 = new Counter();
        c1.inc(); c2.inc(); c1.inc();
        // s is shared: 1, 2, 3
        // local is new each call: always equals s at that moment
    }

    // Q4: null object calling static member
    static void q4() {
        System.out.println("\nQ4: Null object static access");
        class Weird {
            static int x = 42;
            static void hi() { System.out.println("hi! x=" + x); }
        }
        Weird w = null;
        System.out.println(w.x);   // 42 — no NullPointerException! static!
        w.hi();                    // Works! static method, no object needed
    }

    public static void main(String[] args) {
        q1(); q2(); q3(); q4();

        System.out.println("\n── Key Takeaways ──");
        System.out.println("1. null object se static access — NullPointerException NAHI aata");
        System.out.println("2. Static method ref = new Child() → Parent ka method chale");
        System.out.println("3. Static variable sab share karte hain — b1.count = b2.count");
        System.out.println("4. Local variable = method scope mein, static nahi ho sakta");
    }
}
▶ OUTPUT
Q1: Static variable sharing
3
3
3

Q2: Method Hiding
Base
Derived

Q3: Static vs local scope
s=1 local=1
s=2 local=2
s=3 local=3

Q4: Null object static access
42
hi! x=42

── Key Takeaways ──
1. null object se static access — NullPointerException NAHI aata
2. Static method ref = new Child() → Parent ka method chale
3. Static variable sab share karte hain — b1.count = b2.count
4. Local variable = method scope mein, static nahi ho sakta
📁 Program 3 — Complete Interview Q Bank P7.3
Sabse common interview questions ek program mein — yes/no ke saath explanation.
public class InterviewQBank {

    static int x = 5;

    // Q: Can static method be synchronized? YES!
    static synchronized void syncMethod() {
        System.out.println("✅ Q1: static synchronized — YES (class-level lock)");
    }

    // Q: Can we have static method in abstract class? YES!
    static abstract class AbstractBase {
        static void staticInAbstract() {
            System.out.println("✅ Q2: static in abstract class — YES");
        }
        abstract void abstractMethod();  // child implement karega
    }

    // Q: Can interface have static method? YES (Java 8+)
    interface MyInterface {
        static void interfaceStatic() {
            System.out.println("✅ Q3: static in interface — YES (Java 8+)");
        }
    }

    // Q: Can we call static method from constructor? YES
    static void helperFromConstructor() {
        System.out.println("✅ Q4: static from constructor — YES | x=" + x);
    }
    InterviewQBank() {
        helperFromConstructor();
        x++;
    }

    // Q: Can static variable be local (inside method)? NO!
    static void noLocalStatic() {
        // static int localStatic = 5; ← COMPILE ERROR
        int local = 5;  // local variable — static nahi ho sakta
        System.out.println("❌ Q5: local static var — NO (compile error) | local=" + local);
    }

    // Q: Can static method be overridden? NO — only hidden
    static void cannotOverride() {
        System.out.println("❌ Q6: static method override — NO (only method hiding)");
    }

    // Q: Can we use this in static method? NO
    static void noThis() {
        // System.out.println(this.x); ← COMPILE ERROR
        System.out.println("❌ Q7: 'this' in static — NO (compile error)");
    }

    // Q: What is class loading order?
    static { System.out.println("Q8: static block runs at class load — BEFORE main()"); }

    public static void main(String[] args) {
        System.out.println("\n── Interview Q&A ──\n");
        syncMethod();
        AbstractBase.staticInAbstract();
        MyInterface.interfaceStatic();

        System.out.println("Q4: Calling constructor:");
        InterviewQBank obj = new InterviewQBank();
        noLocalStatic();
        cannotOverride();
        noThis();

        System.out.println("\nFinal x = " + x + " (incremented in constructor)");
    }
}
▶ OUTPUT
Q8: static block runs at class load — BEFORE main()

── Interview Q&A ──

✅ Q1: static synchronized — YES (class-level lock)
✅ Q2: static in abstract class — YES
✅ Q3: static in interface — YES (Java 8+)
Q4: Calling constructor:
✅ Q4: static from constructor — YES | x=5
❌ Q5: local static var — NO (compile error) | local=5
❌ Q6: static method override — NO (only method hiding)
❌ Q7: 'this' in static — NO (compile error)

Final x = 6 (incremented in constructor)
📁 Program 4 — Static Thread Safety Issue P7.4
Static variable + multiple threads = race condition. Synchronized se fix karo — important for backend development.
// UNSAFE counter — race condition!
class UnsafeCounter {
    static int count = 0;
    static void increment() { count++; }  // not thread-safe!
}

// SAFE counter — synchronized static method
class SafeCounter {
    private static int count = 0;

    static synchronized void increment() {
        count++;  // class-level lock — only one thread at a time
    }

    static synchronized int getCount() { return count; }
    static synchronized void reset()   { count = 0; }
}

public class ThreadSafetyDemo {

    public static void main(String[] args) throws InterruptedException {

        System.out.println("── Safe Counter Demo ──");

        // Simulate 5 threads each incrementing 100 times
        Thread[] threads = new Thread[5];
        for (int i = 0; i < 5; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 100; j++) {
                    SafeCounter.increment();
                }
            }, "Thread-" + (i+1));
        }

        for (Thread t : threads) t.start();
        for (Thread t : threads) t.join();  // wait for all threads

        System.out.println("Expected : 500");
        System.out.println("Got      : " + SafeCounter.getCount());
        System.out.println("Correct? : " + (SafeCounter.getCount() == 500));

        System.out.println("\n── Key Points ──");
        System.out.println("• static + synchronized = class-level lock");
        System.out.println("• instance + synchronized = object-level lock");
        System.out.println("• Shared static state in multi-threaded apps = potential race condition");
        System.out.println("• Always synchronize when multiple threads share static state");
    }
}
▶ OUTPUT
── Safe Counter Demo ──
Expected : 500
Got      : 500
Correct? : true

── Key Points ──
• static + synchronized = class-level lock
• instance + synchronized = object-level lock
• Shared static state in multi-threaded apps = potential race condition
• Always synchronize when multiple threads share static state
🏭

Topic 8 — Real Backend Patterns with Static

Production-grade code mein static kaise use hota hai

📁 Program 1 — Logger Singleton P8.1
Production-style Logger — Singleton + static counter + timestamp. Real apps mein Log4j/SLF4J isi pattern pe hain.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class AppLogger {

    private static AppLogger instance = null;
    private static int        logCount = 0;
    private static final DateTimeFormatter FMT =
        DateTimeFormatter.ofPattern("HH:mm:ss");

    private String appName;

    private AppLogger(String name) {
        this.appName = name;
        System.out.println("[LOGGER] Logger initialized for: " + appName);
    }

    public static AppLogger getInstance(String name) {
        if (instance == null) instance = new AppLogger(name);
        return instance;
    }

    private String ts() { return LocalDateTime.now().format(FMT); }

    void info (String msg) { log("INFO ", msg); }
    void warn (String msg) { log("WARN ", msg); }
    void error(String msg) { log("ERROR", msg); }
    void debug(String msg) { log("DEBUG", msg); }

    private void log(String level, String msg) {
        logCount++;
        System.out.printf("[%s] [%s] [%s] #%d — %s%n",
                           ts(), level, appName, logCount, msg);
    }

    static int getLogCount() { return logCount; }
}

public class BackendLogger {
    public static void main(String[] args) {
        AppLogger log = AppLogger.getInstance("ECommerceApp");
        AppLogger log2 = AppLogger.getInstance("ECommerceApp"); // same!

        System.out.println("Same instance: " + (log == log2));

        log.info("Server started on port 8080");
        log.info("Database connected");
        log.debug("Request: GET /api/products");
        log.warn("Cache miss ratio above 20%");
        log.info("Response: 200 OK (45ms)");
        log.error("Payment gateway timeout!");
        log2.warn("Retry attempt 1/3");
        log2.info("Retry success");

        System.out.println("\nTotal log entries: " + AppLogger.getLogCount());
    }
}
▶ OUTPUT
[LOGGER] Logger initialized for: ECommerceApp
Same instance: true
[14:32:01] [INFO ] [ECommerceApp] #1 — Server started on port 8080
[14:32:01] [INFO ] [ECommerceApp] #2 — Database connected
[14:32:01] [DEBUG] [ECommerceApp] #3 — Request: GET /api/products
[14:32:01] [WARN ] [ECommerceApp] #4 — Cache miss ratio above 20%
[14:32:01] [INFO ] [ECommerceApp] #5 — Response: 200 OK (45ms)
[14:32:01] [ERROR] [ECommerceApp] #6 — Payment gateway timeout!
[14:32:01] [WARN ] [ECommerceApp] #7 — Retry attempt 1/3
[14:32:01] [INFO ] [ECommerceApp] #8 — Retry success

Total log entries: 8
📁 Program 2 — Static Memoization Cache P8.2
Static HashMap se computationally expensive results cache karo — backend performance optimization ka core concept.
import java.util.*;

class MemoCache {

    // Static cache — program lifetime tak persist karta hai
    private static final Map<Integer, Long> fibCache = new HashMap<>();
    private static final Map<Integer, Long> factCache = new HashMap<>();
    private static int cacheHits = 0;
    private static int cacheMiss = 0;

    static long fib(int n) {
        if (n <= 1) return n;
        if (fibCache.containsKey(n)) { cacheHits++; return fibCache.get(n); }
        cacheMiss++;
        long result = fib(n-1) + fib(n-2);
        fibCache.put(n, result);
        return result;
    }

    static long fact(int n) {
        if (n <= 1) return 1;
        if (factCache.containsKey(n)) { cacheHits++; return factCache.get(n); }
        cacheMiss++;
        long result = n * fact(n-1);
        factCache.put(n, result);
        return result;
    }

    static void printStats() {
        System.out.println("Cache Hits   : " + cacheHits);
        System.out.println("Cache Misses : " + cacheMiss);
        System.out.printf ("Hit Rate     : %.1f%%%n",
                            (double)cacheHits / (cacheHits+cacheMiss) * 100);
        System.out.println("Fib Cache sz : " + fibCache.size());
        System.out.println("Fact Cache sz: " + factCache.size());
    }

    public static void main(String[] args) {
        System.out.println("── First Calls (cache cold) ──");
        long t1 = System.nanoTime();
        System.out.println("fib(40)   = " + fib(40));
        System.out.println("fib(30)   = " + fib(30));
        System.out.println("fact(15)  = " + fact(15));
        long t2 = System.nanoTime();
        System.out.println("Time: " + (t2-t1)/1000 + " μs");

        System.out.println("\n── Second Calls (cache warm) ──");
        long t3 = System.nanoTime();
        System.out.println("fib(40)   = " + fib(40));   // from cache!
        System.out.println("fib(35)   = " + fib(35));   // partially cached
        System.out.println("fact(15)  = " + fact(15));  // from cache!
        long t4 = System.nanoTime();
        System.out.println("Time: " + (t4-t3)/1000 + " μs  ← MUCH faster!");

        System.out.println("\n── Cache Statistics ──");
        printStats();
    }
}
▶ OUTPUT
── First Calls (cache cold) ──
fib(40)   = 102334155
fib(30)   = 832040
fact(15)  = 1307674368000
Time: 842 μs

── Second Calls (cache warm) ──
fib(40)   = 102334155
fib(35)   = 9227465
fact(15)  = 1307674368000
Time: 12 μs  ← MUCH faster!

── Cache Statistics ──
Cache Hits   : 43
Cache Misses : 54
Hit Rate     : 44.3%
Fib Cache sz : 40
Fact Cache sz: 14
📁 Program 3 — Static Router (Spring DispatcherServlet concept) P8.3
Static Map se HTTP routes register karo aur dispatch karo — Spring Boot ka DispatcherServlet isi concept pe kaam karta hai.
import java.util.*;

interface Handler {
    String handle(String method, String body);
}

class Router {

    // Static route registry — program-wide
    private static final Map<String, Handler> routes = new LinkedHashMap<>();
    private static final List<String>        requestLog = new ArrayList<>();
    private static int requestCount = 0;

    // Register route — static method
    static void route(String path, Handler handler) {
        routes.put(path, handler);
        System.out.println("[ROUTER] ✔ Registered: " + path);
    }

    // Dispatch request — static method
    static String dispatch(String method, String path, String body) {
        requestCount++;
        String logEntry = "#" + requestCount + " " + method + " " + path;
        requestLog.add(logEntry);

        Handler h = routes.get(path);
        if (h == null) return "404 Not Found: " + path;
        return h.handle(method, body);
    }

    static void printLog() {
        System.out.println("\n── Request Log ──");
        requestLog.forEach(e -> System.out.println("  " + e));
        System.out.println("Total requests: " + requestCount);
    }
}

public class StaticRouterDemo {

    public static void main(String[] args) {
        // Route registration (like @GetMapping, @PostMapping)
        Router.route("/api/users", (method, body) -> {
            if ("GET".equals(method))  return "200 [{id:1,name:Rahul}, {id:2,name:Priya}]";
            if ("POST".equals(method)) return "201 Created user: " + body;
            return "405 Method Not Allowed";
        });

        Router.route("/api/products", (method, body) -> {
            if ("GET".equals(method))  return "200 [{id:101,name:Laptop,price:75000}]";
            return "405 Method Not Allowed";
        });

        Router.route("/api/health", (m, b) -> "200 {status:UP, uptime:99.9%}");

        System.out.println("\n── Processing Requests ──");
        String[] responses = {
            Router.dispatch("GET",    "/api/users",    null),
            Router.dispatch("POST",   "/api/users",    "{name:Amit,email:amit@g.com}"),
            Router.dispatch("GET",    "/api/products", null),
            Router.dispatch("DELETE", "/api/products", null),
            Router.dispatch("GET",    "/api/health",   null),
            Router.dispatch("GET",    "/api/unknown",  null)
        };

        for (String resp : responses) System.out.println("  → " + resp);
        Router.printLog();
    }
}
▶ OUTPUT
[ROUTER] ✔ Registered: /api/users
[ROUTER] ✔ Registered: /api/products
[ROUTER] ✔ Registered: /api/health

── Processing Requests ──
  → 200 [{id:1,name:Rahul}, {id:2,name:Priya}]
  → 201 Created user: {name:Amit,email:amit@g.com}
  → 200 [{id:101,name:Laptop,price:75000}]
  → 405 Method Not Allowed
  → 200 {status:UP, uptime:99.9%}
  → 404 Not Found: /api/unknown

── Request Log ──
  #1 GET /api/users
  #2 POST /api/users
  #3 GET /api/products
  #4 DELETE /api/products
  #5 GET /api/health
  #6 GET /api/unknown
Total requests: 6
📁 Program 4 — Enum-Style HTTP Status with Static P8.4
Static constants aur methods se HTTP status codes organize karo — real project mein aise constants classes use hoti hain.
class HttpStatus {
    // 2xx Success
    static final int OK          = 200;
    static final int CREATED     = 201;
    static final int ACCEPTED    = 202;
    static final int NO_CONTENT  = 204;
    // 3xx Redirect
    static final int MOVED_PERMANENTLY = 301;
    static final int NOT_MODIFIED      = 304;
    // 4xx Client Error
    static final int BAD_REQUEST   = 400;
    static final int UNAUTHORIZED  = 401;
    static final int FORBIDDEN     = 403;
    static final int NOT_FOUND     = 404;
    static final int CONFLICT      = 409;
    static final int TOO_MANY_REQ  = 429;
    // 5xx Server Error
    static final int SERVER_ERROR  = 500;
    static final int BAD_GATEWAY   = 502;
    static final int UNAVAILABLE   = 503;

    static String message(int code) {
        switch(code) {
            case 200: return "OK";            case 201: return "Created";
            case 202: return "Accepted";      case 204: return "No Content";
            case 301: return "Moved Permanently"; case 304: return "Not Modified";
            case 400: return "Bad Request";   case 401: return "Unauthorized";
            case 403: return "Forbidden";     case 404: return "Not Found";
            case 409: return "Conflict";      case 429: return "Too Many Requests";
            case 500: return "Internal Server Error";
            case 502: return "Bad Gateway";   case 503: return "Service Unavailable";
            default:  return "Unknown";
        }
    }

    static boolean isSuccess(int c)     { return c >= 200 && c < 300; }
    static boolean isRedirect(int c)    { return c >= 300 && c < 400; }
    static boolean isClientError(int c) { return c >= 400 && c < 500; }
    static boolean isServerError(int c) { return c >= 500; }

    static String category(int c) {
        if (isSuccess(c))     return "✅ SUCCESS";
        if (isRedirect(c))    return "↪ REDIRECT";
        if (isClientError(c)) return "❌ CLIENT ERR";
        if (isServerError(c)) return "💥 SERVER ERR";
        return "UNKNOWN";
    }

    public static void main(String[] args) {
        int[] codes = {200,201,301,400,401,403,404,409,429,500,503};
        System.out.printf("%-5s %-25s %-14s%n", "Code", "Message", "Category");
        System.out.println("─".repeat(48));
        for (int c : codes)
            System.out.printf("%-5d %-25s %-14s%n", c, message(c), category(c));

        System.out.println("\n── Usage in code ──");
        int res = 404;
        if (HttpStatus.isClientError(res)) {
            System.out.println("Client made a bad request: " + HttpStatus.message(res));
        }
    }
}
▶ OUTPUT
Code  Message                   Category
────────────────────────────────────────────────
200   OK                        ✅ SUCCESS
201   Created                   ✅ SUCCESS
301   Moved Permanently         ↪ REDIRECT
400   Bad Request               ❌ CLIENT ERR
401   Unauthorized              ❌ CLIENT ERR
403   Forbidden                 ❌ CLIENT ERR
404   Not Found                 ❌ CLIENT ERR
409   Conflict                  ❌ CLIENT ERR
429   Too Many Requests         ❌ CLIENT ERR
500   Internal Server Error     💥 SERVER ERR
503   Service Unavailable       💥 SERVER ERR

── Usage in code ──
Client made a bad request: Not Found

⭐ Complete Quick Reference & Summary

📦 Static Variable
static int count;
Class-level, single copy, all share. Method Area mein store. Default values milti hain.
⚡ Static Method
static void help() {}
Object ke bina call. this/instance nahi. main() isi liye static hai.
🔥 Static Block
static { ... }
Class load pe sirf once. main() se pehle. Config/driver loading ke liye.
🏗️ Static Nested Class
static class Inner {}
Outer object nahi chahiye. Builder, Node patterns mein use hoti hai.
📥 Static Import
import static Math.*;
Class name likhne ki zaroorat nahi. Math ops, JUnit testing mein useful.
🧬 Inheritance + Static
Static = Method Hiding (compile-time). Instance = Overriding (runtime). @Override static pe = warning.
🔒 static final
CONSTANT banata hai. Change nahi ho sakta. Convention: ALL_CAPS naam. JVM mein single copy, compile-time constant.
🔄 Execution Order
Parent static → Child static → Parent constructor → Child constructor. Static blocks sirf ek baar!

🎯 Exam & Interview — Must Remember Points

  • static = Class ka hai, Object ka nahi — Method Area mein store hota hai
  • Static variable — sirf ek copy, sabhi objects share karte hain, class se access karo
  • Static method — object banaye bina call karo: ClassName.method()
  • Static block — class load pe sirf ek baar, main() se bhi pehle
  • Static nested class — outer object ki zaroorat nahi, outer.static members only access
  • Static method — override nahi hota, sirf hide hota hai (Method Hiding)
  • main() static kyun? — JVM object banaye bina call kare isliye
  • Execution order: Parent static → Child static → Parent ctor → Child ctor
  • static final = constant — convention: ALL_CAPS naam rakhte hain
  • Interface mein static method — Java 8+ se allowed, override nahi hota
  • null object se static access — NullPointerException nahi aata!
  • Static variable = global shared state — multi-threading mein careful!

⚠️ Common Mistakes — Wrong vs Right

Situation ❌ Wrong ✅ Right
Instance in static static void m() { instanceVar++; } Object create karo, fir access karo
this in static static void m() { this.x = 5; } this static mein nahi — remove karo
Static via object obj.staticMethod() ← misleading ClassName.staticMethod()
Override static @Override static void greet() Static sirf hide hota hai, @Override nahi
Local static var void m() { static int x = 5; } Local variables static nahi ho sakte
Static block dobara 10 objects → static block 10 baar chala Static block sirf EK baar — class load pe
Nested class creation new Outer().new Static.Nested() new Outer.StaticNested()
Thread safety Multiple threads ek static var modify karein static synchronized method use karo

🏆 Golden Rule

"static = Class ka member, Object ka nahi — yeh ek cheez yaad karo, baaki sab samajh aayega"

☕ Java Static Keyword & Class — Complete Deep Guide | Keep Coding! 🚀