📚 Topics Covered

📦

Topic 1 — Static Variable (Class Variable)

Memory model, sharing, constants, real-world use

🧠 Static Variable kya hai?

Static variable ek aise variable ko kehte hain jo class ke saath belong karta hai, kisi individual object ke saath nahi. Jab bhi aap static keyword lagaate ho kisi variable ke saath, toh Java us variable ka sirf ek hi copy banata hai — poore program ke liye. Chahe aap 100 objects banao, sab usi ek copy ko share karte hain.

Memory mein kahan store hota hai? Instance variables Heap mein store hote hain (har object ke saath alag-alag). Static variables Method Area (ya Class Area) mein store hote hain — ye memory ek baar allocate hoti hai jab class JVM mein load hoti hai.

Access kaise karte hain? Best practice hai — class ke naam se: ClassName.variableName. Object reference se bhi ho sakta hai lekin yeh misleading hota hai aur IDE warnings deta hai.

Static vs Instance Variable — Memory Layout ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CLASS AREA (Method Area) HEAP (Object Memory) ┌─────────────────────────┐ ┌──────────────────────────────┐ │ Student.college = "IIT"│ │ obj1: { name="Rahul", age=21}│ │ Student.count = 3 │ │ obj2: { name="Amit", age=22}│ └─────────────────────────┘ │ obj3: { name="Priya", age=20}│ ↑ SIRF EK copy └──────────────────────────────┘ sab objects yahan point karte ↑ HAR OBJECT ka alag copy obj1.college → same as Student.college (same memory location!) obj2.college → same as Student.college (same memory location!) Isliye: obj1.count == obj2.count == Student.count ← HAMESHA!
💡
Kab use karein? Jab koi value sabhi objects ke liye same ho — jaise bank ka naam, company name, kisi counter ka value, ya koi configuration constant. static final se constants banate hain (ALL_CAPS convention).
  • Static variable class load hote waqt initialize hota hai (object banane se pehle)
  • Sabhi objects ke beech shared hai — ek mein change → sab ko effect
  • ClassName.varName se access karna best practice hai
  • Object-specific data ko static variable mein mat rakhein — wrong design hai
  • Multi-threading mein static variables thread-safety issues cause karte hain

Program 1.1 — Object Counter using Static Variable
Har baar new object banta hai toh shared counter increment hota hai. Teen objects ke baad counter = 3.
ObjectCounter.java
public class ObjectCounter {

    // static variable — sirf ek copy, sabhi objects share karte hain
    static int count = 0;

    // instance variable — har object ka apna
    String name;
    int    id;

    ObjectCounter(String name) {
        count++;               // shared counter badho
        this.id   = count;
        this.name = name;
        System.out.println("Object Created: " + name + " | ID: " + id + " | Total: " + count);
    }

    static void showTotal() {
        System.out.println("Total objects created: " + count);
    }

    public static void main(String[] args) {

        System.out.println("--- Before creating objects ---");
        ObjectCounter.showTotal();  // class name se access — BEST way

        ObjectCounter s1 = new ObjectCounter("Rahul");
        ObjectCounter s2 = new ObjectCounter("Amit");
        ObjectCounter s3 = new ObjectCounter("Priya");

        System.out.println("\n--- After creating 3 objects ---");
        System.out.println("Class access   : " + ObjectCounter.count);  // 3
        System.out.println("Via s1         : " + s1.count);               // 3
        System.out.println("Via s2         : " + s2.count);               // 3 — sab same!

        System.out.println("\ns1.name = " + s1.name + " | s2.name = " + s2.name);
        // name alag-alag (instance variable)
    }
}
OUTPUT
--- Before creating objects ---
Total objects created: 0
Object Created: Rahul | ID: 1 | Total: 1
Object Created: Amit  | ID: 2 | Total: 2
Object Created: Priya | ID: 3 | Total: 3

--- After creating 3 objects ---
Class access   : 3
Via s1         : 3
Via s2         : 3   ← sab same memory location!

s1.name = Rahul | s2.name = Amit
Program 1.2 — Bank Account with Shared Interest Rate
Bank name aur interest rate static hai (sabka same), lekin account holder aur balance instance variable hai (individual).
BankAccount.java
class BankAccount {

    // ─── Static (shared by all accounts) ───────────────────────
    static String  bankName     = "State Bank of India";
    static double  interestRate = 7.5;
    static int     totalAccounts = 0;

    // ─── Instance (individual per account) ─────────────────────
    String holder;
    long   accNo;
    double balance;

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

    void showDetails() {
        double interest = balance * interestRate / 100;
        System.out.printf("[%-15s] Acc: %d | Bal: ₹%8.0f | Rate: %.1f%% | Interest: ₹%.0f%n",
                           holder, accNo, balance, interestRate, interest);
    }

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

        System.out.println("Bank: " + BankAccount.bankName);
        System.out.println("Total Accounts: " + BankAccount.totalAccounts);
        System.out.println("─".repeat(75));
        a1.showDetails();
        a2.showDetails();
        a3.showDetails();

        System.out.println("\n★ RBI ne interest rate change kiya to 8.0%...");
        BankAccount.interestRate = 8.0;   // ek jagah badla → sabko effect!
        System.out.println("─".repeat(75));
        a1.showDetails();
        a2.showDetails();
        a3.showDetails();
    }
}
OUTPUT
Bank: State Bank of India
Total Accounts: 3
───────────────────────────────────────────────────────────────────────────
[Rahul Sharma   ] Acc: 10012345 | Bal: ₹  50000 | Rate: 7.5% | Interest: ₹3750
[Priya Singh    ] Acc: 10067890 | Bal: ₹  80000 | Rate: 7.5% | Interest: ₹6000
[Amit Kumar     ] Acc: 10099001 | Bal: ₹ 120000 | Rate: 7.5% | Interest: ₹9000

★ RBI ne interest rate change kiya to 8.0%...
───────────────────────────────────────────────────────────────────────────
[Rahul Sharma   ] Acc: 10012345 | Bal: ₹  50000 | Rate: 8.0% | Interest: ₹4000
[Priya Singh    ] Acc: 10067890 | Bal: ₹  80000 | Rate: 8.0% | Interest: ₹6400
[Amit Kumar     ] Acc: 10099001 | Bal: ₹ 120000 | Rate: 8.0% | Interest: ₹9600
Program 1.3 — Static Final Constants
Constants define karna — static final se. Convention: ALL_CAPS names. Compile-time constant ban jaata hai.
AppConstants.java
class AppConstants {

    // static final = constant — change karne pe COMPILE ERROR!
    static final double PI          = 3.14159265358979;
    static final int    MAX_USERS   = 1000;
    static final String APP_NAME    = "BackendApp";
    static final String VERSION     = "v2.5.0";
    static final double TAX_RATE    = 0.18;

    // static mutable variable (shared state)
    static int    activeUsers  = 0;
    static String currentTheme = "light";

    public static void main(String[] args) {

        System.out.println("=== App Configuration ===");
        System.out.println("App     : " + AppConstants.APP_NAME);
        System.out.println("Version : " + AppConstants.VERSION);
        System.out.println("MaxUsers: " + AppConstants.MAX_USERS);
        System.out.println("TaxRate : " + (AppConstants.TAX_RATE * 100) + "%");
        System.out.println("PI      : " + AppConstants.PI);

        // Tax calculation using constant
        double price = 1500.0;
        double total = price + (price * AppConstants.TAX_RATE);
        System.out.printf("\nPrice: ₹%.0f | Tax: ₹%.0f | Total: ₹%.0f%n",
                           price, price * AppConstants.TAX_RATE, total);

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

        // PI.PI = 3.0; ← COMPILE ERROR: cannot assign a value to final variable
        System.out.println("\nCircle area (r=7): " + AppConstants.PI * 7 * 7);
    }
}
OUTPUT
=== App Configuration ===
App     : BackendApp
Version : v2.5.0
MaxUsers: 1000
TaxRate : 18.0%
PI      : 3.14159265358979

Price: ₹1500 | Tax: ₹270 | Total: ₹1770

Active users: 45
After login : 46

Circle area (r=7): 153.9380...
Program 1.4 — Singleton Pattern with Static Variable
Static variable se ensure karo ki poori application mein sirf ek hi object bane (Singleton Design Pattern).
Singleton.java
class DatabaseConnection {

    // static instance — sirf ek object kabhi bhi exist karega
    private static DatabaseConnection instance = null;
    private static int connectionAttempts = 0;

    private String url;
    private String status;

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

    // static factory method — ek hi instance deta hai
    public static DatabaseConnection getInstance() {
        connectionAttempts++;
        if (instance == null) {
            System.out.println("[DB] Creating new connection (first time)...");
            instance = new DatabaseConnection();
        } else {
            System.out.println("[DB] Reusing existing connection.");
        }
        return instance;
    }

    void query(String sql) {
        System.out.println("[DB] Executing: " + sql);
    }

    static int getAttempts() { return connectionAttempts; }

    public static void main(String[] args) {
        DatabaseConnection db1 = DatabaseConnection.getInstance();
        DatabaseConnection db2 = DatabaseConnection.getInstance();
        DatabaseConnection db3 = DatabaseConnection.getInstance();

        System.out.println("\ndb1 == db2: " + (db1 == db2));  // true!
        System.out.println("db2 == db3: " + (db2 == db3));  // true!
        System.out.println("Connection attempts: " + DatabaseConnection.getAttempts());
        System.out.println("Actual connections created: 1 (Singleton!)");

        db1.query("SELECT * FROM users WHERE id = 5");
        db3.query("INSERT INTO orders VALUES (101, 'Rahul', 500)");
    }
}
OUTPUT
[DB] Creating new connection (first time)...
[DB] Connection established: jdbc:mysql://localhost:3306/mydb
[DB] Reusing existing connection.
[DB] Reusing existing connection.

db1 == db2: true
db2 == db3: true
Connection attempts: 3
Actual connections created: 1 (Singleton!)
[DB] Executing: SELECT * FROM users WHERE id = 5
[DB] Executing: INSERT INTO orders VALUES (101, 'Rahul', 500)
Program 1.5 — Instance vs Static Comparison
Ek hi class mein dono type variables — difference clearly dekhein.
InstanceVsStatic.java
class Vehicle {
    // ── Static (class-level shared) ───────────────────────────────
    static String manufacturer  = "Tata Motors";
    static int    totalVehicles = 0;

    // ── Instance (per-object individual) ──────────────────────────
    String model;
    int    year;
    double price;

    Vehicle(String model, int year, double price) {
        this.model = model;
        this.year  = year;
        this.price = price;
        totalVehicles++;
    }

    void info() {
        System.out.printf("%-10s %-6d ₹%-10.0f  %s%n", model, year, price, manufacturer);
    }

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

        System.out.println("Model      Year   Price         Manufacturer");
        System.out.println("─".repeat(52));
        v1.info(); v2.info(); v3.info(); v4.info();
        System.out.println("Total: " + Vehicle.totalVehicles + " vehicles");

        System.out.println("\n★ Manufacturer name update:");
        Vehicle.manufacturer = "Tata Motors Ltd.";   // ek jagah badla → sab pe effect
        v1.info(); v2.info();
    }
}
OUTPUT
Model      Year   Price         Manufacturer
────────────────────────────────────────────────────
Nexon      2023   ₹900000      Tata Motors
Punch      2022   ₹700000      Tata Motors
Safari     2024   ₹1800000     Tata Motors
Harrier    2023   ₹1500000     Tata Motors
Total: 4 vehicles

★ Manufacturer name update:
Nexon      2023   ₹900000      Tata Motors Ltd.
Punch      2022   ₹700000      Tata Motors Ltd.
⚙️

Topic 2 — Static Method

Object-independent methods, rules, utility patterns, main() mystery

🧠 Static Method kya hai?

Static method woh method hai jo class ke saath belong karta hai. Ise call karne ke liye koi object banane ki zaroorat nahi hoti. Aap directly class ke naam se call kar sakte ho: ClassName.methodName().

Kaise kaam karta hai internally? Jab Java compiler static method dekhta hai, toh woh use compile-time pe class ke saath bind karta hai. Runtime pe JVM ise call karta hai bina kisi object reference ke. Isliye this keyword ka koi matlab nahi static method mein.

Common use cases: Utility/helper methods (Math.sqrt, Integer.parseInt), Factory methods (object create karne ke liye), Validation methods, main() entry point.

Static Method — Rules (CRITICAL!) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ static method INSIDE mein: ✅ static variable access kar sakta hai ✅ static method call kar sakta hai ✅ local variables use kar sakta hai ✅ object banakar instance members access kar sakta hai ❌ instance variable directly access NAHI kar sakta ❌ instance method directly call NAHI kar sakta ❌ 'this' keyword USE NAHI kar sakta ❌ 'super' keyword USE NAHI kar sakta Kyun? Static method tab bhi exist karta hai jab koi object nahi hota — "this" ka matlab hi nahi! Call karein: ClassName.method() ← BEST obj.method() ← works but misleading (avoid)
ℹ️
main() static kyun hai? JVM ko program start karne ke liye ek entry point chahiye. Agar main() static na hota, toh JVM ko pehle koi object banana padta — lekin kaunsi class ka? Isliye main() static hai — JVM directly ClassName.main(args) call karta hai, bina koi object banaye.
Program 2.1 — Basic Static Method Rules
Static aur instance method ke beech ki boundary clearly demonstrate karna.
StaticMethodBasics.java
public class StaticMethodBasics {

    static int  count = 0;       // static variable
    String      name;             // instance variable

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

    // ── Static Method ─────────────────────────────────────────
    static void staticDemo() {
        System.out.println("[Static] count = " + count);       // ✅ OK
        // System.out.println(name);  ← COMPILE ERROR!
        // instanceDemo();            ← COMPILE ERROR!
        // this.count = 5;            ← COMPILE ERROR!

        // FIX: object banakar access karo
        StaticMethodBasics temp = new StaticMethodBasics("Temp");
        System.out.println("[Static via obj] name = " + temp.name); // ✅
    }

    // ── Instance Method ───────────────────────────────────────
    void instanceDemo() {
        System.out.println("[Instance] name=" + name + " count=" + count); // dono ✅
        staticDemo();  // ✅ instance method static call kar sakta hai
    }

    // ── Utility static methods ────────────────────────────────
    static int     add(int a, int b)    { return a + b; }
    static int     max(int a, int b)    { return a > b ? a : b; }
    static boolean isEven(int n)         { return n % 2 == 0; }
    static String  repeat(String s, int n){ return s.repeat(n); }

    public static void main(String[] args) {

        // Object banaye bina static call!
        System.out.println("add(7,3)  = "  + StaticMethodBasics.add(7,3));
        System.out.println("max(9,4)  = "  + StaticMethodBasics.max(9,4));
        System.out.println("isEven(6) = " + StaticMethodBasics.isEven(6));

        StaticMethodBasics obj = new StaticMethodBasics("Rahul");
        obj.instanceDemo();
    }
}
OUTPUT
add(7,3)  = 10
max(9,4)  = 9
isEven(6) = true
[Static] count = 0
[Static via obj] name = Temp
[Instance] name=Rahul count=2
[Static] count = 2
[Static via obj] name = Temp
Program 2.2 — Utility Class (Math Library Style)
Pure static class jisme sirf utility methods hain — Java ke Math class jaisi. Object banane ki zaroorat hi nahi.
MathUtils.java
class MathUtils {

    // private constructor — koi object nahi bana sakta!
    private MathUtils() {}

    static int     add(int a, int b)          { return a + b; }
    static int     subtract(int a, int b)      { return a - b; }
    static double  divide(double a, double b)  { return b == 0 ? 0 : a/b; }

    static int power(int base, int exp) {
        int result = 1;
        for (int i = 0; i < exp; i++) result *= base;
        return result;
    }

    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) {
        return n <= 1 ? 1 : n * factorial(n - 1); // recursive static call ✅
    }

    static int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    static boolean isPalindrome(String s) {
        return s.equals(new StringBuilder(s).reverse().toString());
    }

    public static void main(String[] args) {
        // Koi object nahi! Seedha class se call
        System.out.println("power(2, 10)   = " + MathUtils.power(2, 10));
        System.out.println("factorial(7)   = " + MathUtils.factorial(7));
        System.out.println("gcd(48, 18)    = " + MathUtils.gcd(48, 18));
        System.out.println("isPrime(29)    = " + MathUtils.isPrime(29));
        System.out.println("isPalindrome('racecar') = " + MathUtils.isPalindrome("racecar"));
        System.out.println("divide(10, 0)  = " + MathUtils.divide(10, 0)  + " (safe)");
    }
}
OUTPUT
power(2, 10)   = 1024
factorial(7)   = 5040
gcd(48, 18)    = 6
isPrime(29)    = true
isPalindrome('racecar') = true
divide(10, 0)  = 0.0 (safe)
Program 2.3 — Static Factory Method Pattern
Static method se different types ke objects banana — constructor ke bajaaye. Real frameworks mein common pattern.
UserFactory.java
class User {

    private String  username;
    private String  email;
    private String  role;
    private boolean active;
    private static int userCount = 0;

    // private constructor — sirf static methods se banta hai
    private User(String username, String email, String role) {
        this.username = username;
        this.email    = email;
        this.role     = role;
        this.active   = true;
        userCount++;
    }

    // ── Static Factory Methods ────────────────────────────────
    static User createAdmin(String username, String email) {
        if (!isValidEmail(email)) return null;
        System.out.println("[USER] Creating ADMIN: " + username);
        return new User(username, email, "ADMIN");
    }

    static User createCustomer(String username, String email) {
        if (!isValidEmail(email)) return null;
        System.out.println("[USER] Creating CUSTOMER: " + username);
        return new User(username, email, "CUSTOMER");
    }

    static User createGuest() {
        long ts = System.currentTimeMillis() % 10000;
        System.out.println("[USER] Creating GUEST...");
        return new User("guest_" + ts, "guest@temp.com", "GUEST");
    }

    // ── Static Validation ────────────────────────────────────
    static boolean isValidEmail(String email) {
        return email != null && email.contains("@") && email.contains(".")
               && email.indexOf("@") > 0;
    }

    static boolean isValidUsername(String u) {
        return u != null && u.length() >= 3 && u.matches("[a-zA-Z0-9_]+");
    }

    void show() {
        System.out.printf("  %-20s %-30s %-10s %s%n",
                           username, email, role, active ? "Active" : "Inactive");
    }

    public static void main(String[] args) {
        System.out.println("=== User Creation with Factory Methods ===");
        User admin    = User.createAdmin("superadmin", "admin@company.com");
        User customer = User.createCustomer("rahul_99", "rahul@gmail.com");
        User guest    = User.createGuest();
        User invalid  = User.createCustomer("bad", "notanemail");

        System.out.println("\n  Username             Email                          Role       Status");
        System.out.println("  " + "─".repeat(78));
        if (admin    != null) admin.show();
        if (customer != null) customer.show();
        if (guest    != null) guest.show();
        System.out.println("  invalid user → null (bad email)");

        System.out.println("\nTotal users created: " + userCount);
        System.out.println("\nValidation tests:");
        System.out.println("  isValidEmail('a@b.com') = " + User.isValidEmail("a@b.com"));
        System.out.println("  isValidEmail('notgood') = " + User.isValidEmail("notgood"));
    }
}
OUTPUT
=== User Creation with Factory Methods ===
[USER] Creating ADMIN: superadmin
[USER] Creating CUSTOMER: rahul_99
[USER] Creating GUEST...

  Username             Email                          Role       Status
  ──────────────────────────────────────────────────────────────────────────────
  superadmin           admin@company.com              ADMIN      Active
  rahul_99             rahul@gmail.com                CUSTOMER   Active
  guest_5734           guest@temp.com                 GUEST      Active
  invalid user → null (bad email)

Total users created: 3

Validation tests:
  isValidEmail('a@b.com') = true
  isValidEmail('notgood') = false
Program 2.4 — Static Method Cannot be Overridden (Method Hiding)
Important interview topic — static method override nahi hota, sirf hide hota hai. Compile-time vs Runtime binding.
MethodHiding.java
class Animal {
    static void sound() {                   // static — override NAHI hoga
        System.out.println("Animal makes sound (static)");
    }
    void move() {                            // instance — override HOGA
        System.out.println("Animal moves (instance)");
    }
}

class Dog extends Animal {
    static void sound() {                   // Method HIDING (not override)
        System.out.println("Dog barks (static)");
    }
    @Override
    void move() {                            // TRUE override
        System.out.println("Dog runs (instance)");
    }
}

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

        Animal ref = new Dog();  // Dog object, Animal reference

        System.out.println("=== ref = new Dog() — Animal reference ===");
        ref.sound();         // Animal's! (compile-time → reference type decide karta hai)
        ref.move();          // Dog's!   (runtime → actual object decide karta hai)

        System.out.println("\n=== Direct class calls ===");
        Animal.sound();      // Animal's
        Dog.sound();         // Dog's

        Dog dog = new Dog();
        dog.sound();         // Dog's (reference type = Dog)
        dog.move();          // Dog's

        System.out.println("\n=== KEY RULE ===");
        System.out.println("Static  → Compile-time binding → reference ka method");
        System.out.println("Instance→ Runtime binding     → actual object ka method");
        System.out.println("Static = Method HIDING, NOT Overriding!");
    }
}
OUTPUT
=== ref = new Dog() — Animal reference ===
Animal makes sound (static)   ← compile-time! Animal reference ka method
Dog runs (instance)           ← runtime! Dog object ka method

=== Direct class calls ===
Animal makes sound (static)
Dog barks (static)
Dog barks (static)
Dog runs (instance)

=== KEY RULE ===
Static  → Compile-time binding → reference ka method
Instance→ Runtime binding     → actual object ka method
Static = Method HIDING, NOT Overriding!
🔴
Interview Trap! Static method @Override nahi hota — agar likhein bhi toh compiler warning deta hai. Animal ref = new Dog() mein ref.sound() Animal ka chalega, Dog ka nahi. Yeh runtime polymorphism NAHI hai.

Topic 3 — Static Block (Static Initializer)

Class load pe one-time initialization, execution order, real use cases

🧠 Static Block kya hai?

Static block (ya static initializer) ek special block hai jo static { ... } syntax se likhte hain. Yeh block class jab pehli baar JVM mein load hoti hai tab automatically execute hota hai — chahe koi object na bana ho, chahe main() bhi na chalai ho!

Key properties: (1) Sirf ek baar run hota hai — class load pe. (2) Object banane se pehle run hota hai. (3) main() se bhi pehle run hota hai. (4) Multiple static blocks likh sakte ho — top to bottom order mein execute hote hain.

Use cases: Database driver loading (Class.forName()), Configuration file padhna, Complex static variable initialization, One-time setup logic jo constructor se pehle hona chahiye.

Execution Order — Class Lifecycle ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ JVM Program Start ↓ 1️⃣ Parent class ke static variables initialize (default values) 2️⃣ Parent class ka static block run (top-to-bottom) 3️⃣ Child class ke static variables initialize 4️⃣ Child class ka static block run (top-to-bottom) ↓ main() execute starts ↓ (jab new Object() hota hai) 5️⃣ Instance initializer block (non-static {}) 6️⃣ Constructor run ↓ (dusra new Object() → sirf 5 aur 6 repeat, static blocks nahi) Static blocks = class load pe ONCE Constructors = har naye object ke liye
Program 3.1 — Static Block Basics & Execution Order
Static block main() se pehle chalta hai, sirf ek baar. Teen objects ke baad bhi static block dobara nahi chala.
StaticBlockBasics.java
public class StaticBlockBasics {

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

    // Static Block — class load hote waqt SIRF EK BAAR
    static {
        System.out.println("[STATIC BLOCK] Running! (before main)");
        x       = 100;
        y       = 200;
        message = "Initialized in static block!";
        System.out.println("[STATIC BLOCK] x=" + x + " y=" + y);
    }

    int instanceVar;

    StaticBlockBasics(int val) {
        this.instanceVar = val;
        System.out.println("[CONSTRUCTOR] instanceVar=" + val);
    }

    public static void main(String[] args) {
        System.out.println("[MAIN] main() started");

        System.out.println("\n--- Creating Object 1:");
        StaticBlockBasics obj1 = new StaticBlockBasics(10);

        System.out.println("\n--- Creating Object 2:");
        StaticBlockBasics obj2 = new StaticBlockBasics(20);

        System.out.println("\n--- Creating Object 3:");
        StaticBlockBasics obj3 = new StaticBlockBasics(30);

        System.out.println("\nFinal: x=" + x + " message=" + message);
    }
}
OUTPUT
[STATIC BLOCK] Running! (before main)    ← main() se pehle!
[STATIC BLOCK] x=100 y=200
[MAIN] main() started

--- Creating Object 1:
[CONSTRUCTOR] instanceVar=10

--- Creating Object 2:
[CONSTRUCTOR] instanceVar=20

--- Creating Object 3:
[CONSTRUCTOR] instanceVar=30

Final: x=100 message=Initialized in static block!
↑ Static block sirf EK BAAR chala, 3 constructors chale!
Program 3.2 — Multiple Static Blocks & Order
Ek class mein kaafi static blocks likh sakte hain — top-to-bottom order mein execute hote hain.
MultipleStaticBlocks.java
public class MultipleStaticBlocks {

    static int a = initA();   // static method se initialize
    static int b;
    static int c;

    static {                   // First static block
        System.out.println("[Block 1] a=" + a);
        b = 20;
        System.out.println("[Block 1] b set to " + b);
    }

    static int d = 40;         // variable between blocks

    static {                   // Second static block
        System.out.println("[Block 2] b=" + b + " d=" + d);
        c = a + b + d;
        System.out.println("[Block 2] c = a+b+d = " + a + "+" + b + "+" + d + "=" + c);
    }

    static int initA() {
        System.out.println("[initA()] called for a");
        return 10;
    }

    public static void main(String[] args) {
        System.out.println("\n[MAIN] executing...");
        System.out.println("a=" + a + " b=" + b + " c=" + c + " d=" + d);
    }
}
OUTPUT
[initA()] called for a
[Block 1] a=10
[Block 1] b set to 20
[Block 2] b=20 d=40
[Block 2] c = a+b+d = 10+20+40=70

[MAIN] executing...
a=10 b=20 c=70 d=40
Program 3.3 — Parent-Child Static Block Execution Order
Inheritance mein kaunsa static block pehle chalta hai? Parent pehle, phir Child — yeh interview mein poochha jaata hai!
InheritanceBlockOrder.java
class Parent {
    static int pVal = 10;

    static {
        System.out.println("1️⃣  Parent static block | pVal=" + pVal);
        pVal = 20;
    }

    Parent() {
        System.out.println("3️⃣  Parent Constructor");
    }
}

class Child extends Parent {
    static int cVal = 30;

    static {
        System.out.println("2️⃣  Child static block | cVal=" + cVal);
        cVal = 40;
    }

    Child() {
        // super() implicit — Parent constructor pehle chalega
        System.out.println("4️⃣  Child Constructor");
    }
}

public class InheritanceBlockOrder {
    public static void main(String[] args) {
        System.out.println("=== Creating first Child object ===");
        Child c1 = new Child();

        System.out.println("\n=== Creating second Child object ===");
        Child c2 = new Child();  // static blocks nahi chalenge dobara

        System.out.println("\nFinal: pVal=" + Parent.pVal + " cVal=" + Child.cVal);
    }
}
OUTPUT
=== Creating first Child object ===
1️⃣  Parent static block | pVal=10
2️⃣  Child static block | cVal=30
3️⃣  Parent Constructor
4️⃣  Child Constructor

=== Creating second Child object ===
3️⃣  Parent Constructor           ← static blocks nahi, sirf constructors
4️⃣  Child Constructor

Final: pVal=20 cVal=40
Program 3.4 — Static Block: Config Loading (Real Use Case)
Real backend applications mein static block se configuration aur database settings load karte hain — application start pe.
AppConfig.java
class AppConfig {

    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 boolean       configLoaded = false;

    // Static block: application start pe sirf ek baar config load
    static {
        System.out.println("[CONFIG] ━━━ Loading Configuration ━━━");
        long start = System.currentTimeMillis();

        // Real app mein: Properties file ya env variables se padhna
        DB_HOST   = System.getenv("DB_HOST")  != null
                  ? System.getenv("DB_HOST")  : "localhost";
        DB_PORT   = 3306;
        DB_NAME   = "backend_db";
        POOL_SIZE = 10;
        LOG_LEVEL = "INFO";

        System.out.println("[CONFIG] DB_HOST   = " + DB_HOST);
        System.out.println("[CONFIG] DB_PORT   = " + DB_PORT);
        System.out.println("[CONFIG] DB_NAME   = " + DB_NAME);
        System.out.println("[CONFIG] POOL_SIZE = " + POOL_SIZE);
        System.out.println("[CONFIG] LOG_LEVEL = " + LOG_LEVEL);

        configLoaded = true;
        long end = System.currentTimeMillis();
        System.out.println("[CONFIG] Loaded in " + (end - start) + "ms ✓");
    }

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

    public static void main(String[] args) {
        System.out.println("\n[APP] Application starting...");
        System.out.println("[APP] JDBC URL   : " + AppConfig.getJdbcUrl());
        System.out.println("[APP] Pool size  : " + AppConfig.POOL_SIZE);
        System.out.println("[APP] Config OK  : " + AppConfig.configLoaded);
    }
}
OUTPUT
[CONFIG] ━━━ Loading Configuration ━━━
[CONFIG] DB_HOST   = localhost
[CONFIG] DB_PORT   = 3306
[CONFIG] DB_NAME   = backend_db
[CONFIG] POOL_SIZE = 10
[CONFIG] LOG_LEVEL = INFO
[CONFIG] Loaded in 0ms ✓

[APP] Application starting...
[APP] JDBC URL   : jdbc:mysql://localhost:3306/backend_db
[APP] Pool size  : 10
[APP] Config OK  : true
🏗️

Topic 4 — Static Nested Class

Inner vs Static nested, Builder pattern, Node structure, real API patterns

🧠 Static Nested Class kya hai?

Java mein 4 types ke nested classes hote hain: Static Nested Class, Inner Class, Local Class, aur Anonymous Class. Static Nested Class woh hai jisme static keyword laga hota hai.

Sabse bada fark: Static nested class ko create karne ke liye outer class ka object banana nahi padta. Aap directly new Outer.NestedClass() likh sakte ho. Normal (non-static) inner class mein outer object compulsory hai.

Restrictions: Static nested class outer class ke sirf static members access kar sakti hai. Instance variables nahi. Kyunki? Kyunki koi outer object exist hi nahi karta necessarily.

Best use cases: Builder Pattern (most common!), Data structure nodes (LinkedList.Node), Helper classes jo outer class ke context mein sense karti hain lekin independently bhi kaam kar sakti hain.

✅ Static Nested Class

Outer.Nested obj = new Outer.Nested();

• Outer object ki zaroorat NAHI
• Sirf outer ke static members access
• Independent existence
• Builder, Node patterns mein use

⚠️ Non-Static Inner Class

Outer o = new Outer();
Outer.Inner i = o.new Inner();


• Outer object COMPULSORY hai
• Outer ke sab members access
• Outer object se tied
• Outer state pe dependent logic
Program 4.1 — Static vs Non-Static Nested Classes
Dono type ke nested classes ek saath dekhein — difference clearly samajh aayega.
NestedClassDemo.java
public class NestedClassDemo {

    private int    outerInstance = 42;   // instance variable
    private static int outerStatic  = 99;  // static variable

    // ── Static Nested Class ───────────────────────────────────
    static class StaticNested {
        int nestedVal = 50;

        void display() {
            System.out.println("[StaticNested] outerStatic  = " + outerStatic);   // ✅
            // outerInstance ← COMPILE ERROR (no outer object!)
            System.out.println("[StaticNested] nestedVal = " + nestedVal);
        }
    }

    // ── Non-Static Inner Class ────────────────────────────────
    class InnerClass {
        void display() {
            System.out.println("[InnerClass] outerInstance = " + outerInstance); // ✅
            System.out.println("[InnerClass] outerStatic   = " + outerStatic);   // ✅
        }
    }

    public static void main(String[] args) {

        System.out.println("=== Static Nested (no outer object needed) ===");
        NestedClassDemo.StaticNested sn = new NestedClassDemo.StaticNested();
        sn.display();

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

        System.out.println("\n=== Summary ===");
        System.out.println("Static Nested → new Outer.Nested()     (no outer obj)");
        System.out.println("Inner Class   → outerObj.new Inner()   (outer needed)");
    }
}
OUTPUT
=== Static Nested (no outer object needed) ===
[StaticNested] outerStatic  = 99
[StaticNested] nestedVal = 50

=== Inner Class (outer object REQUIRED) ===
[InnerClass] outerInstance = 42
[InnerClass] outerStatic   = 99

=== Summary ===
Static Nested → new Outer.Nested()     (no outer obj)
Inner Class   → outerObj.new Inner()   (outer needed)
Program 4.2 — Builder Pattern (Most Common Static Nested Use)
Builder pattern mein static nested class ka sabse popular use — readable, flexible object creation. Lombok @Builder isi pe based hai.
BuilderPattern.java
class Employee {

    private final String name;
    private final String email;
    private final String dept;
    private final double salary;
    private final String role;
    private final int    yearsExp;

    // Private constructor — sirf Builder se banana possible
    private Employee(Builder b) {
        this.name     = b.name;
        this.email    = b.email;
        this.dept     = b.dept;
        this.salary   = b.salary;
        this.role     = b.role;
        this.yearsExp = b.yearsExp;
    }

    // ★ STATIC NESTED BUILDER ★
    static class Builder {
        private String name;             // required
        private String email;            // required
        private String dept    = "General";   // optional (default)
        private double salary  = 30000;       // optional
        private String role    = "Associate";  // optional
        private int    yearsExp= 0;            // optional

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

        // Fluent setters — return this for chaining
        Builder dept(String d)    { this.dept    = d; return this; }
        Builder salary(double s)  { this.salary  = s; return this; }
        Builder role(String r)    { this.role    = r; return this; }
        Builder exp(int e)        { this.yearsExp= e; return this; }
        Employee build()         { return new Employee(this); }
    }

    void display() {
        System.out.printf("  %-18s %-30s %-14s %-12s ₹%.0f | %d yrs%n",
                           name, email, dept, role, salary, yearsExp);
    }

    public static void main(String[] args) {

        // Builder pattern — method chaining, clear code!
        Employee e1 = new Employee.Builder("Rahul Sharma", "rahul@co.com")
                            .dept("Engineering")
                            .role("Senior Dev")
                            .salary(85000)
                            .exp(4)
                            .build();

        Employee e2 = new Employee.Builder("Priya Singh", "priya@co.com")
                            .dept("Design")
                            .role("UX Lead")
                            .salary(70000)
                            .exp(3)
                            .build();

        // Minimal — optional fields default values lenge
        Employee e3 = new Employee.Builder("Amit Patel", "amit@co.com").build();

        System.out.println("  Name               Email                          Dept           Role         Salary  | Exp");
        System.out.println("  " + "─".repeat(100));
        e1.display();
        e2.display();
        e3.display();
    }
}
OUTPUT
  Name               Email                          Dept           Role         Salary  | Exp
  ────────────────────────────────────────────────────────────────────────────────────────────────────
  Rahul Sharma       rahul@co.com                   Engineering    Senior Dev   ₹85000 | 4 yrs
  Priya Singh        priya@co.com                   Design         UX Lead      ₹70000 | 3 yrs
  Amit Patel         amit@co.com                    General        Associate    ₹30000 | 0 yrs
Program 4.3 — LinkedList Node using Static Nested Class
Data structures mein static nested class ka classic use — Node class ko independently create karna.
LinkedListWithNode.java
public class LinkedListWithNode {

    // Static Nested Node class — outer object ki zaroorat nahi
    static class Node {
        int  data;
        Node next;

        Node(int data) { this.data = data; this.next = null; }
    }

    static Node head = null;

    static void addLast(int data) {
        Node newNode = new Node(data);  // no outer object!
        if (head == null) { head = newNode; return; }
        Node curr = head;
        while (curr.next != null) curr = curr.next;
        curr.next = newNode;
    }

    static void addFirst(int data) {
        Node n = new Node(data);
        n.next = head; head = n;
    }

    static void print() {
        Node curr = head;
        System.out.print("List: HEAD → ");
        while (curr != null) {
            System.out.print("[" + curr.data + "]");
            if (curr.next != null) System.out.print(" → ");
            curr = curr.next;
        }
        System.out.println(" → NULL");
    }

    static int size() {
        int count = 0;
        Node curr = head;
        while (curr != null) { count++; curr = curr.next; }
        return count;
    }

    public static void main(String[] args) {
        addLast(10); addLast(20); addLast(30);
        addFirst(5);
        addLast(40);
        print();
        System.out.println("Size: " + size());

        // Node ko independently use karo — koi LinkedListWithNode object nahi!
        LinkedListWithNode.Node standalone = new LinkedListWithNode.Node(99);
        System.out.println("Standalone node data: " + standalone.data);
    }
}
OUTPUT
List: HEAD → [5] → [10] → [20] → [30] → [40] → NULL
Size: 5
Standalone node data: 99
Program 4.4 — API Response with Static Nested Classes
Real backend pattern — static factory methods aur nested static data classes se structured API responses banana.
ApiResponse.java
public class ApiResponse {

    private int     statusCode;
    private String  message;
    private Object  data;
    private boolean success;

    private ApiResponse(int code, String msg, Object data, boolean ok) {
        this.statusCode = code; this.message = msg;
        this.data = data;       this.success = ok;
    }

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

    // ★ Static Nested Data Classes ★
    static class UserData {
        String id, name, email, role;
        UserData(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+"\" }";
        }
    }

    void print(String endpoint) {
        System.out.println("\n→ " + endpoint);
        System.out.println("  { \"status\": "  + statusCode
                         + ", \"success\": "  + success
                         + ", \"message\": \""+ message + "\"");
        System.out.println("    \"data\": "    + data + " }");
    }

    public static void main(String[] args) {

        ApiResponse.UserData user = new ApiResponse.UserData("U001", "Rahul", "r@g.com", "ADMIN");

        ApiResponse.ok("User found", user).print("GET /api/users/U001");
        ApiResponse.created("User created", user).print("POST /api/users");
        ApiResponse.notFound("User not found").print("GET /api/users/XYZ");
        ApiResponse.serverError("DB connection failed").print("GET /api/orders");
    }
}
OUTPUT
→ GET /api/users/U001
  { "status": 200, "success": true, "message": "User found"
    "data": { id: "U001", name: "Rahul", email: "r@g.com", role: "ADMIN" } }

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

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

→ GET /api/orders
  { "status": 500, "success": false, "message": "DB connection failed"
    "data": null }
📥

Topic 5 — Static Import

Class name ke bina static members use karna, Math ops, JUnit style

🧠 Static Import kya hai?

Static import (Java 5+) ek feature hai jisse aap kisi doosri class ke static members (variables aur methods) ko directly use kar sakte ho — class ka naam likhne ki zaroorat nahi hoti.

Syntax:
import static java.lang.Math.PI; — sirf PI import
import static java.lang.Math.*; — Math ke saare static members

Kab use karein: Jab ek hi class ke bahut saare static members use ho rahe hain aur class ka naam likhna code ko verbose bana raha ho (scientific calculations, test assertions mein).

Kab avoid karein: Jab ambiguity ho (do classes mein same naam ka static method), jab reader ko pata na chale ki method kahan se aaya, jab code less readable ho jaye.

Program 5.1 — Static Import Basics (Math class)
Math.sqrt(), Math.PI etc. ko bina "Math." ke use karna — scientific calculations mein code cleaner lagta hai.
StaticImportBasics.java
import static java.lang.Math.*;     // sab Math static members
import static java.lang.System.out; // System.out ko "out" se access

public class StaticImportBasics {

    public static void main(String[] args) {

        // Without static import (verbose):
        // System.out.println("PI = " + Math.PI);
        // System.out.println(Math.sqrt(25));

        // With static import (clean!):
        out.println("PI        = " + PI);           // Math.PI
        out.println("E         = " + E);            // Math.E
        out.println("sqrt(25)  = " + sqrt(25));    // Math.sqrt
        out.println("pow(2,10) = " + pow(2, 10));  // Math.pow
        out.println("abs(-42)  = " + abs(-42));   // Math.abs
        out.println("ceil(4.2) = " + ceil(4.2));  // Math.ceil
        out.println("floor(4.9)= " + floor(4.9)); // Math.floor
        out.println("max(7,3)  = " + max(7, 3));  // Math.max
        out.println("sin(PI/2) = " + sin(PI/2));  // Math.sin
        out.println("log(E)    = " + log(E));     // log(e) = 1

        // Geometry calculations — very clean with static import
        out.println("\n=== Geometry ===");
        double r = 7.0;
        out.printf("Circle area (r=%.0f)  = %.4f%n", r, PI * r * r);
        out.printf("Circle perimeter     = %.4f%n", 2 * PI * r);
        out.printf("Hypotenuse (3,4)     = %.1f%n",  sqrt(3*3 + 4*4));
    }
}
OUTPUT
PI        = 3.141592653589793
E         = 2.718281828459045
sqrt(25)  = 5.0
pow(2,10) = 1024.0
abs(-42)  = 42
ceil(4.2) = 5.0
floor(4.9)= 4.0
max(7,3)  = 7
sin(PI/2) = 1.0
log(E)    = 1.0

=== Geometry ===
Circle area (r=7)  = 153.9380
Circle perimeter   = 43.9823
Hypotenuse (3,4)   = 5.0
Program 5.2 — Custom Constants with Static Import
Apni constants class ke members ko static import karna — pura class naam nahi likhna padta.
CustomStaticImport.java
// Step 1: Constants class define karo
class HttpConstants {
    public static final int    OK          = 200;
    public static final int    CREATED     = 201;
    public static final int    NOT_FOUND   = 404;
    public static final int    SERVER_ERR  = 500;
    public static final String BASE_URL    = "https://api.example.com";
    public static final double TIMEOUT_SEC = 30.0;

    public static String getDesc(int code) {
        return switch (code) {
            case 200 -> "OK";
            case 201 -> "Created";
            case 404 -> "Not Found";
            case 500 -> "Internal Server Error";
            default  -> "Unknown";
        };
    }
}

// Step 2: Static import — in alag file mein hoga
// import static HttpConstants.*;

// Step 3: Use karo without class name
public class CustomStaticImport {
    public static void main(String[] args) {

        // Without static import (same file demo):
        System.out.println("=== HTTP Status Demo ===");
        int[] codes = {HttpConstants.OK, HttpConstants.CREATED,
                       HttpConstants.NOT_FOUND, HttpConstants.SERVER_ERR};

        for (int code : codes) {
            System.out.printf("  %d → %s%n", code, HttpConstants.getDesc(code));
        }

        System.out.println("\nBase URL: "  + HttpConstants.BASE_URL);
        System.out.println("Timeout : "  + HttpConstants.TIMEOUT_SEC + "s");

        // Alag file mein static import ke saath:
        // import static HttpConstants.*;
        // System.out.println(OK);           // directly OK
        // System.out.println(getDesc(404));  // directly getDesc()
        // System.out.println(BASE_URL);      // directly BASE_URL

        System.out.println("\n=== With static import, code would look like: ===");
        System.out.println("  System.out.println(OK);           // 200");
        System.out.println("  System.out.println(getDesc(404)); // Not Found");
        System.out.println("  System.out.println(BASE_URL);     // https://...");
    }
}
OUTPUT
=== HTTP Status Demo ===
  200 → OK
  201 → Created
  404 → Not Found
  500 → Internal Server Error

Base URL: https://api.example.com
Timeout : 30.0s

=== With static import, code would look like: ===
  System.out.println(OK);           // 200
  System.out.println(getDesc(404)); // Not Found
  System.out.println(BASE_URL);     // https://...
Program 5.3 — JUnit Style Testing with Static Import
Testing mein static import ka sabse practical use — assertions seedhe likhein bina class name ke.
JUnitStyleTest.java
import static java.lang.Math.*;
import static java.lang.System.out;

public class JUnitStyleTest {

    // Custom assertion methods (JUnit jaisa — import static se direct use)
    static int passed = 0, failed = 0;

    static void assertEquals(Object expected, Object actual, String name) {
        if (expected.equals(actual)) {
            out.println("  ✅ PASS: " + name); passed++;
        } else {
            out.println("  ❌ FAIL: " + name + " | Expected: " + expected + " | Got: " + actual);
            failed++;
        }
    }

    static void assertTrue(boolean cond, String name) {
        out.println(cond ? "  ✅ PASS: " + name : "  ❌ FAIL: " + name);
        if (cond) passed++; else failed++;
    }

    // Methods under test
    static int     square(int n)          { return n * n; }
    static double  circleArea(double r)   { return PI * r * r; }  // PI from Math.*
    static boolean isPalin(String s)      { return s.equals(new StringBuilder(s).reverse().toString()); }

    public static void main(String[] args) {
        out.println("=== Running Test Suite ===");

        out.println("\n[square() tests]");
        assertEquals(25,  square(5),  "square(5)  == 25");
        assertEquals(100, square(10), "square(10) == 100");
        assertEquals(0,   square(0),  "square(0)  == 0");
        assertEquals(1,   square(1),  "square(1)  == 1");

        out.println("\n[circleArea() tests]");
        assertTrue(abs(circleArea(5) - 78.5398) < 0.001, "circleArea(5) ≈ 78.54");
        assertTrue(abs(circleArea(1) - PI) < 0.0001,       "circleArea(1) == PI");

        out.println("\n[isPalin() tests]");
        assertTrue(isPalin("racecar"),  "'racecar' is palindrome");
        assertTrue(isPalin("madam"),    "'madam' is palindrome");
        assertTrue(!isPalin("hello"),   "'hello' NOT palindrome");

        out.println("\n[String tests]");
        assertEquals("HELLO", "hello".toUpperCase(), "toUpperCase");
        assertEquals(5, "hello".length(), "length of 'hello'");

        out.printf("\n=== Results: %d passed, %d failed ===%n", passed, failed);
    }
}
OUTPUT
=== Running Test Suite ===

[square() tests]
  ✅ PASS: square(5)  == 25
  ✅ PASS: square(10) == 100
  ✅ PASS: square(0)  == 0
  ✅ PASS: square(1)  == 1

[circleArea() tests]
  ✅ PASS: circleArea(5) ≈ 78.54
  ✅ PASS: circleArea(1) == PI

[isPalin() tests]
  ✅ PASS: 'racecar' is palindrome
  ✅ PASS: 'madam' is palindrome
  ✅ PASS: 'hello' NOT palindrome

[String tests]
  ✅ PASS: toUpperCase
  ✅ PASS: length of 'hello'

=== Results: 11 passed, 0 failed ===
⚠️
Static Import — Kab AVOID karein: (1) Jab do alag classes mein same naam ka method ho — ambiguity aayegi. (2) Jab reader ko pata na chale ki method/variable kahan se aaya. (3) Jab code ki readability decrease ho. Rule of thumb: agar Math.sqrt() likhna zyada clear hai toh static import avoid karo.
🧬

Topic 6 — Static in Inheritance

Method hiding vs overriding, execution order, interface static methods

🧠 Static aur Inheritance — Deep Theory

Instance method override hota hai (Runtime Polymorphism): Jab child class parent ka instance method redefine karta hai, toh @Override annotation lagta hai aur runtime pe actual object ke type ke hisaab se method call hoti hai.

Static method override NAHI hota — hide hota hai (Method Hiding): Child class mein same naam aur signature ka static method likhna "Method Hiding" hai. Jab aap parent reference mein child object rakhte ho aur static method call karte ho, reference type decide karta hai kaunsi method chalegi — actual object nahi. Yeh compile-time binding hai.

Interface mein static methods (Java 8+): Java 8 se interfaces mein static methods allowed hain. Lekin ye interface ke through directly call nahi hoti — InterfaceName.method() se call karte hain. Implementing class mein ise override nahi kar sakte.

Program 6.1 — Method Hiding Complete Demo
Static method hiding vs instance method overriding ka poora comparison — compile-time vs runtime binding clearly dekhein.
MethodHidingVsOverride.java
class Base {
    static String type = "Base";       // static variable

    static void staticInfo() {         // STATIC METHOD — override nahi
        System.out.println("Base.staticInfo() | type=" + type);
    }

    void instanceInfo() {              // INSTANCE METHOD — override hoga
        System.out.println("Base.instanceInfo() | type=" + type);
    }
}

class Derived extends Base {
    static String type = "Derived";   // variable hiding

    static void staticInfo() {         // METHOD HIDING (NOT override!)
        System.out.println("Derived.staticInfo() | type=" + type);
    }

    @Override
    void instanceInfo() {              // TRUE OVERRIDE
        System.out.println("Derived.instanceInfo() | type=" + type);
    }
}

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

        Base    baseRef    = new Base();
        Derived derivedRef = new Derived();
        Base    polyRef    = new Derived(); // Polymorphic!

        System.out.println("=== baseRef (Base ref + Base obj) ===");
        baseRef.staticInfo();    // Base
        baseRef.instanceInfo();  // Base

        System.out.println("\n=== derivedRef (Derived ref + Derived obj) ===");
        derivedRef.staticInfo();   // Derived
        derivedRef.instanceInfo(); // Derived

        System.out.println("\n=== polyRef (Base ref + Derived obj) — KEY! ===");
        polyRef.staticInfo();    // BASE! (compile-time → ref type = Base)
        polyRef.instanceInfo();  // DERIVED! (runtime → object type = Derived)

        System.out.println("\n=== Direct class access ===");
        Base.staticInfo();     // Base
        Derived.staticInfo(); // Derived

        System.out.println("\n=== Variable Hiding ===");
        System.out.println("polyRef.type   = " + polyRef.type);     // Base! (compile-time)
        System.out.println("Base.type      = " + Base.type);
        System.out.println("Derived.type   = " + Derived.type);
    }
}
OUTPUT
=== baseRef (Base ref + Base obj) ===
Base.staticInfo() | type=Base
Base.instanceInfo() | type=Base

=== derivedRef (Derived ref + Derived obj) ===
Derived.staticInfo() | type=Derived
Derived.instanceInfo() | type=Derived

=== polyRef (Base ref + Derived obj) — KEY! ===
Base.staticInfo() | type=Base        ← compile-time! Base reference = Base method
Derived.instanceInfo() | type=Derived ← runtime! Derived object = Derived method

=== Direct class access ===
Base.staticInfo() | type=Base
Derived.staticInfo() | type=Derived

=== Variable Hiding ===
polyRef.type   = Base      ← compile-time! reference type decides
Base.type      = Base
Derived.type   = Derived
Program 6.2 — Static Members in Inheritance (Shared Counter)
Parent class ka static variable sabhi subclasses ke beech share hota hai — poori hierarchy ka shared state.
InheritedStaticVar.java
class Animal {
    static int  population = 0;     // shared across ALL subclasses!
    static String kingdom = "Animalia";
    String      name;

    Animal(String name) {
        this.name = name;
        population++;   // shared — Dog, Cat, Bird sab badhate hain
    }

    static void showPopulation() {
        System.out.println("[Kingdom: " + kingdom + "] Population: " + population);
    }
}

class Dog extends Animal {
    String breed;
    Dog(String name, String breed) { super(name); this.breed = breed; }
    void info() {
        System.out.println("🐕 Dog: " + name + " | Breed: " + breed + " | Kingdom: " + kingdom);
    }
}

class Cat extends Animal {
    Cat(String name) { super(name); }
    void info() {
        System.out.println("🐱 Cat: " + name + " | Kingdom: " + kingdom);
    }
}

class Bird extends Animal {
    Bird(String name) { super(name); }
    void info() {
        System.out.println("🐦 Bird: " + name + " | Kingdom: " + kingdom);
    }
}

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

        Animal.showPopulation(); // 0

        Dog  d1 = new Dog("Bruno",    "Labrador");
        Dog  d2 = new Dog("Rocky",    "Pomeranian");
        Cat  c1 = new Cat("Whiskers");
        Bird b1 = new Bird("Tweety");

        d1.info(); d2.info(); c1.info(); b1.info();

        System.out.println();
        Animal.showPopulation(); // 4 (all subtypes counted!)
        Dog.showPopulation();    // same! inherited static method
        System.out.println("Dog.kingdom = " + Dog.kingdom);  // inherited static var
    }
}
OUTPUT
[Kingdom: Animalia] Population: 0
🐕 Dog: Bruno | Breed: Labrador | Kingdom: Animalia
🐕 Dog: Rocky | Breed: Pomeranian | Kingdom: Animalia
🐱 Cat: Whiskers | Kingdom: Animalia
🐦 Bird: Tweety | Kingdom: Animalia

[Kingdom: Animalia] Population: 4
[Kingdom: Animalia] Population: 4    ← same as Animal!
Dog.kingdom = Animalia
Program 6.3 — Interface Static Methods (Java 8+)
Interface mein static methods Java 8 se allowed hain — factory methods aur utility methods define kar sakte hain interface mein.
InterfaceStaticMethods.java
interface Validator {
    // Abstract method (implement karna zaroori)
    boolean validate(String input);

    // Static methods in interface (Java 8+) — override NAHI hota!
    static Validator emailValidator() {
        return input -> input != null
                       && input.contains("@")
                       && input.contains(".")
                       && input.indexOf("@") > 0;
    }

    static Validator phoneValidator() {
        return input -> input != null && input.matches("[0-9]{10}");
    }

    static Validator notEmptyValidator() {
        return input -> input != null && !input.trim().isEmpty();
    }

    // Default method (override kar sakte hain)
    default void check(String input, String field) {
        boolean ok = validate(input);
        System.out.printf("  %-12s %-20s → %s%n",
                           field + ":", "\"" + input + "\"",
                           ok ? "✅ Valid" : "❌ Invalid");
    }
}

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

        // Interface static methods — interface name se call
        Validator emailV = Validator.emailValidator();
        Validator phoneV = Validator.phoneValidator();
        Validator notMpty = Validator.notEmptyValidator();

        System.out.println("=== Email Validation ===");
        emailV.check("rahul@gmail.com", "Email");
        emailV.check("notanemail",      "Email");
        emailV.check("",                 "Email");

        System.out.println("\n=== Phone Validation ===");
        phoneV.check("9876543210", "Phone");
        phoneV.check("12345",      "Phone");
        phoneV.check("abcdefghij", "Phone");

        System.out.println("\n=== Not Empty ===");
        notMpty.check("Hello World", "Field");
        notMpty.check("   ",          "Field");
        notMpty.check("",             "Field");
    }
}
OUTPUT
=== Email Validation ===
  Email:       "rahul@gmail.com"    → ✅ Valid
  Email:       "notanemail"         → ❌ Invalid
  Email:       ""                   → ❌ Invalid

=== Phone Validation ===
  Phone:       "9876543210"         → ✅ Valid
  Phone:       "12345"              → ❌ Invalid
  Phone:       "abcdefghij"         → ❌ Invalid

=== Not Empty ===
  Field:       "Hello World"        → ✅ Valid
  Field:       "   "                → ❌ Invalid
  Field:       ""                   → ❌ Invalid
⚠️

Topic 7 — Common Mistakes & Interview Questions

Compile errors, execution order quiz, tricky patterns

Program 7.1 — Static Method mein Instance Access (Compile Error Fix)
Sabse common mistake — static method mein instance variable directly access karna. Error kya hai aur fix kya hai.
CommonMistake1.java
public class CommonMistake1 {

    int    instanceVar = 10;
    static int staticVar  = 20;

    void instanceMethod() {
        System.out.println("Instance method: " + instanceVar + " " + staticVar);
    }

    static void staticMethod() {
        System.out.println("staticVar = " + staticVar);    // ✅ OK

        // ── WRONG — Compile Errors ──────────────────────────────
        // System.out.println(instanceVar);  → ERROR: non-static field
        // instanceMethod();                 → ERROR: non-static method
        // this.staticVar = 5;               → ERROR: 'this' in static context

        // ── CORRECT Fix ─────────────────────────────────────────
        CommonMistake1 obj = new CommonMistake1();
        System.out.println("instanceVar via obj = " + obj.instanceVar);  // ✅
        obj.instanceMethod();                                               // ✅
    }

    public static void main(String[] args) {
        staticMethod();

        CommonMistake1 o = new CommonMistake1();
        o.instanceMethod();
    }
}
OUTPUT
staticVar = 20
instanceVar via obj = 10
Instance method: 10 20
Instance method: 10 20
Program 7.2 — Execution Order Interview Question
Interview mein puchha jaata hai: "Is code ka output kya hoga?" — Static blocks, instance blocks, constructors ka order.
ExecutionOrderQuiz.java
class QuizParent {
    static int pStatic = initPS();

    static {
        System.out.println("1. QuizParent static block");
    }

    {
        System.out.println("3. QuizParent instance block");
    }

    QuizParent() {
        System.out.println("4. QuizParent constructor");
    }

    static int initPS() {
        System.out.println("0. QuizParent static var init");
        return 1;
    }
}

class QuizChild extends QuizParent {
    static {
        System.out.println("2. QuizChild static block");
    }

    {
        System.out.println("5. QuizChild instance block");
    }

    QuizChild() {
        System.out.println("6. QuizChild constructor");
    }
}

public class ExecutionOrderQuiz {
    public static void main(String[] args) {
        System.out.println("=== new QuizChild() ===");
        QuizChild c1 = new QuizChild();

        System.out.println("\n=== new QuizChild() again ===");
        QuizChild c2 = new QuizChild();
        // Static blocks nahi chalenge — sirf instance blocks + constructors
    }
}
OUTPUT
=== new QuizChild() ===
0. QuizParent static var init     ← static variable initialization
1. QuizParent static block        ← parent static block
2. QuizChild static block         ← child static block
3. QuizParent instance block      ← parent instance block
4. QuizParent constructor         ← parent constructor
5. QuizChild instance block       ← child instance block
6. QuizChild constructor          ← child constructor

=== new QuizChild() again ===
3. QuizParent instance block      ← static blocks nahi chale dobara!
4. QuizParent constructor
5. QuizChild instance block
6. QuizChild constructor
📝
Golden Rule for Execution Order:
1st time: Parent static var → Parent static block → Child static block → Parent instance block → Parent constructor → Child instance block → Child constructor
2nd time onward: Static blocks skip, sirf instance blocks + constructors repeat.
Program 7.3 — Interview Q Bank (All Common Questions)
Static keyword ke baare mein sabse zyada pooche jaane waale interview questions ke answers code mein.
InterviewQuestions.java
public class InterviewQuestions {

    static int x = 5;

    // Q1: Can static method be called from constructor? YES
    static void helper() { System.out.println("Static helper: x=" + x); x++; }
    InterviewQuestions() { helper(); /* ✅ YES */ }

    // Q2: Can static method be synchronized? YES
    static synchronized void syncMethod() {
        System.out.println("Synchronized static — class-level lock (Class object)");
    }

    // Q3: Can local variable be static? NO
    static void localVarTest() {
        int local = 10;           // ✅ OK
        // static int local = 10;  ← COMPILE ERROR — local cannot be static
        System.out.println("local var (non-static): " + local);
    }

    // Q4: Can interface have static methods? YES (Java 8+)
    interface Demo {
        static void greet() { System.out.println("Interface static method — Java 8+"); }
    }

    // Q5: Can abstract class have static method? YES
    static abstract class AbstractHelper {
        static void staticInAbstract() {
            System.out.println("Static in abstract class — allowed!");
        }
        abstract void abstractMethod();
    }

    // Q6: Can we override static method? NO — only Method Hiding
    static void overrideTest() {
        System.out.println("Static cannot be @Overridden — only HIDDEN in subclass");
        System.out.println("'Animal ref = new Dog()' → ref.static() calls Animal's method");
    }

    // Q7: Why is main() static?
    static void whyMainStatic() {
        System.out.println("JVM calls: ClassName.main(args) — no object needed");
        System.out.println("If main() were instance method, JVM can't call without object");
        System.out.println("Chicken-egg problem: object banane se pehle code banana padta!");
    }

    public static void main(String[] args) {

        System.out.println("Q1: static from constructor:");
        new InterviewQuestions();
        new InterviewQuestions();

        System.out.println("\nQ2: synchronized static:");
        syncMethod();

        System.out.println("\nQ3: local variable:");
        localVarTest();

        System.out.println("\nQ4: interface static:");
        Demo.greet();

        System.out.println("\nQ5: abstract class static:");
        AbstractHelper.staticInAbstract();

        System.out.println("\nQ6: Override:");
        overrideTest();

        System.out.println("\nQ7: main() static:");
        whyMainStatic();

        System.out.println("\nFinal x = " + x);  // 7 (5 + 2 constructor calls)
    }
}
OUTPUT
Q1: static from constructor:
Static helper: x=5
Static helper: x=6

Q2: synchronized static:
Synchronized static — class-level lock (Class object)

Q3: local variable:
local var (non-static): 10

Q4: interface static:
Interface static method — Java 8+

Q5: abstract class static:
Static in abstract class — allowed!

Q6: Override:
Static cannot be @Overridden — only HIDDEN in subclass
'Animal ref = new Dog()' → ref.static() calls Animal's method

Q7: main() static:
JVM calls: ClassName.main(args) — no object needed
If main() were instance method, JVM can't call without object
Chicken-egg problem: object banane se pehle code banana padta!

Final x = 7
🚀

Topic 8 — Static in Real Backend Patterns

Singleton Logger, Connection Pool, Cache, Router

🧠 Real-World Backend mein Static kahan use hota hai?

Singleton Patternstatic private instance + static getInstance(): Logger, DB Connection, Cache Manager mein ek hi object ensure karna.

Connection Poolstatic shared resources: Limited connections manage karna efficiently. Spring ke DataSource pool isi concept pe kaam karta hai.

Static Cache / Memoizationstatic Map: Repeated expensive computations ka result cache karna — sab calls ke liye same cache accessible.

Registry Patternstatic Map<String, Handler>: Spring Boot ke Route mapping, plugin systems, Command patterns mein use hota hai.

Program 8.1 — Singleton Logger (Production Style)
SingletonLogger.java
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class AppLogger {

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

    private String appName;

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

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

    private void log(String level, String msg) {
        logCounter++;
        String ts = LocalDateTime.now().format(FMT);
        System.out.printf("[%s] [%-5s] [%s] #%03d %s%n",
                           ts, level, appName, logCounter, msg);
    }

    void info(String m)  { log("INFO", m); }
    void warn(String m)  { log("WARN", m); }
    void error(String m) { log("ERROR", m); }
    static int getCount() { return logCounter; }

    public static void main(String[] args) {
        AppLogger log1 = AppLogger.getInstance("BackendApp");
        AppLogger log2 = AppLogger.getInstance("BackendApp");
        System.out.println("Same instance: " + (log1 == log2));

        log1.info("Server started on port 8080");
        log2.warn("Connection pool 80% full");
        log1.info("GET /api/users → 200 OK");
        log1.error("DB timeout after 30s");
        log2.info("Retry attempt 1/3...");

        System.out.println("Total logs: " + AppLogger.getCount());
    }
}
OUTPUT
[LOGGER] Initialized for: BackendApp
Same instance: true
[14:32:01] [INFO ] [BackendApp] #001 Server started on port 8080
[14:32:01] [WARN ] [BackendApp] #002 Connection pool 80% full
[14:32:01] [INFO ] [BackendApp] #003 GET /api/users → 200 OK
[14:32:01] [ERROR] [BackendApp] #004 DB timeout after 30s
[14:32:01] [INFO ] [BackendApp] #005 Retry attempt 1/3...
Total logs: 5
Program 8.2 — Static Cache (Memoization)
StaticCache.java
import java.util.HashMap;
import java.util.Map;

class FibCache {

    // Static cache — sabhi calls ke liye shared memory
    private static Map<Integer, Long> cache = new HashMap<>();
    private static int hits = 0, misses = 0;

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

    static void stats() {
        System.out.printf("Cache stats → hits: %d | misses: %d | size: %d%n",
                           hits, misses, cache.size());
    }

    public static void main(String[] args) {
        System.out.println("fib(10) = " + fib(10));
        System.out.println("fib(20) = " + fib(20));
        System.out.println("fib(10) = " + fib(10)); // from cache!
        System.out.println("fib(40) = " + fib(40));
        System.out.println("fib(50) = " + fib(50));
        stats();
        System.out.println("cache[10] = " + cache.get(10));
    }
}
OUTPUT
fib(10) = 55
fib(20) = 6765
fib(10) = 55      ← instant from cache!
fib(40) = 102334155
fib(50) = 12586269025
Cache stats → hits: 29 | misses: 49 | size: 50
cache[10] = 55

📋 Complete Summary & Quick Reference

static variable

Class-level, single copy, Method Area mein. Sabhi objects share karte hain. ClassName.var se access karo.

static method

Object banaye bina call karo. Instance members access nahi. this/super nahi. Utility, factory, main().

static block

Class load pe sirf ek baar. main() se bhi pehle. Complex initialization ke liye. Multiple blocks allowed.

static nested class

Outer object ki zaroorat nahi. Sirf outer static members access. Builder, Node patterns mein use.

static import

Class naam likhne ki zaroorat nahi. Math.*, System.out import. Scientific calculations, tests mein useful.

Method Hiding

Static method override nahi hota — sirf hide hota hai. Compile-time binding. Reference type decide karta hai.

Execution Order

Parent static → Child static → Parent instance/constructor → Child instance/constructor. Static = once only.

static final

Constants — change karne pe COMPILE ERROR. Convention: ALL_CAPS. Compile-time constant optimization.

⭐ Exam / Interview Sheet

Golden Rule
static = Class ka member — Object ka nahi. Object bane ya na bane, static hamesha available hai!
☕ Java Static Keyword Complete Guide — Keep Coding! 🚀