🧠 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 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.varNamese 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
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) } }
--- 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
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(); } }
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
static final se. Convention: ALL_CAPS names. Compile-time constant ban jaata hai.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); } }
=== 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...
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)"); } }
[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)
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(); } }
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.
🧠 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.
ClassName.main(args) call karta hai, bina koi object banaye.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(); } }
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
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)"); } }
power(2, 10) = 1024
factorial(7) = 5040
gcd(48, 18) = 6
isPrime(29) = true
isPalindrome('racecar') = true
divide(10, 0) = 0.0 (safe)
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")); } }
=== 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
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!"); } }
=== 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!
@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.🧠 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.
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); } }
[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!
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); } }
[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
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); } }
=== 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
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); } }
[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
🧠 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
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)"); } }
=== 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)
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(); } }
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
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); } }
List: HEAD → [5] → [10] → [20] → [30] → [40] → NULL Size: 5 Standalone node data: 99
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"); } }
→ 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 }
🧠 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.
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)); } }
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
// 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://..."); } }
=== 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://...
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); } }
=== 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 ===
Math.sqrt() likhna zyada clear hai toh static import avoid karo.🧠 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.
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); } }
=== 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
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 } }
[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
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"); } }
=== 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
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(); } }
staticVar = 20 instanceVar via obj = 10 Instance method: 10 20 Instance method: 10 20
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 } }
=== 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
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.
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) } }
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
🧠 Real-World Backend mein Static kahan use hota hai?
Singleton Pattern — static private instance + static getInstance(): Logger, DB Connection, Cache Manager mein ek hi object ensure karna.
Connection Pool — static shared resources: Limited connections manage karna efficiently. Spring ke DataSource pool isi concept pe kaam karta hai.
Static Cache / Memoization — static Map: Repeated expensive computations ka result cache karna — sab calls ke liye same cache accessible.
Registry Pattern — static Map<String, Handler>: Spring Boot ke Route mapping, plugin systems, Command patterns mein use hota hai.
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()); } }
[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
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)); } }
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
- ✅static = Class ka hai, Object ka nahi — Method Area mein store hota hai
- ✅Static variable: sirf ek copy, sabhi objects share, class load pe initialize
- ✅Static method: object banaye bina call —
ClassName.method() - ✅Static block: class load pe sirf ek baar, main() se bhi pehle chalta hai
- ✅Static nested class: outer object ki zaroorat nahi —
new Outer.Nested() - ✅Static method override nahi hota — sirf Method Hiding hoti hai (compile-time binding)
- ✅main() static kyun? — JVM object banaye bina directly call kare isliye
- ✅Order: Parent static → Child static → Parent constructor → Child constructor
- ✅Interface mein static methods — Java 8+, override nahi hota, class name se call
- ❌Static method mein this keyword use nahi hota — no object context
- ❌Static method mein instance variable directly access nahi hota
- ❌Local variable (method ke andar) static nahi ho sakta
- ❌Static method
@Overrideannotation ke saath — warning, override nahi hoga - ⚠️Static variable se global shared state banta hai — multi-threading mein careful
- ⚠️
obj.staticMethod()kaam karta hai lekin misleading — avoid karo
static = Class ka member — Object ka nahi. Object bane ya na bane, static hamesha available hai!