Static Keyword — Foundation Theory
Java mein static ka mool concept — memory se leke behaviour tak
Static ka matlab hai — "Class ka member, Object ka nahi." Jab kisi variable, method, block, ya class ko static keyword se mark karte hain, toh woh class se directly associated ho jaata hai, na ki kisi particular object se.
Normal (non-static) members ko access karne ke liye pehle object banana padta hai. Static members ko class name se directly access kiya jaata hai — object ki koi zaroorat nahi hoti.
Memory mein kahan store hota hai? Static members Method Area (ya Class Area) mein store hote hain, jabki instance variables Heap mein har object ke saath store hote hain. Isliye static ka ek hi copy hota hai — chahe aap 1 object banao ya 1000.
Topic 1 — Static Variable (Class Variable)
Class-level shared data — ek copy, sab share karte hain
Static variable ko class variable bhi kehte hain. Yeh class ke saath associate hota hai, na ki kisi object ke saath. JVM mein class load hote hi yeh variable Method Area mein create ho jaata hai aur program ke end tak wahan rehta hai.
Key Characteristics:
- Single copy: Puri JVM mein sirf ek hi copy hoti hai. Chahe 100 objects banao — sab usi ek variable ko share karte hain.
- Class se access: Best practice hai
ClassName.variablese access karna. Object se bhi ho sakta hai (obj.variable) lekin misleading lagta hai aur IDE warning deta hai. - Default values: Instance variables ki tarah static variables ko bhi default values milti hain (int=0, boolean=false, object=null).
- Lifetime: Class load se leke class unload (JVM shutdown) tak — ye sabse lambi lifetime hai Java mein.
Kab use karein? Jab ek value sabhi objects ke liye same ho — jaise bank ka naam, company ka naam, object counter, shared configuration values, constants (static final).
- Access:
ClassName.variable← best;obj.variable← allowed but misleading - Memory: Method Area mein store hota hai, Heap mein nahi
- Scope: Class ke andar kahin bhi accessible — static aur instance dono methods mein
- Constant:
static final= constant — convention: ALL_CAPS naam (jaiseMAX_SIZE) - Thread Safety: Multiple threads ek hi static variable change kar sakti hain — synchronization zaroori
- Override: Static variables override nahi hote — sirf hide hote hain (child mein same naam ka variable)
public class StaticVariable1 {
// ── Static variable: sabhi objects share karte hain ──
static int objectCount = 0;
// ── Instance variables: har object ka apna ──
String name;
int age;
// Constructor: har baar object banta hai toh count badhta hai
StaticVariable1(String name, int age) {
this.name = name;
this.age = age;
objectCount++; // shared counter — ek jagah badha, sab ko effect
System.out.println("✔ Object created: " + name +
" | Total now: " + objectCount);
}
public static void main(String[] args) {
// Object banne se pehle bhi static variable exist karta hai!
System.out.println("Before any object: count = " + objectCount);
StaticVariable1 s1 = new StaticVariable1("Rahul", 21);
StaticVariable1 s2 = new StaticVariable1("Amit", 22);
StaticVariable1 s3 = new StaticVariable1("Priya", 20);
System.out.println("\n── After 3 objects ──");
// Teeno same value dikhate hain — same memory!
System.out.println("Class access : StaticVariable1.objectCount = " + StaticVariable1.objectCount);
System.out.println("Via s1 : s1.objectCount = " + s1.objectCount);
System.out.println("Via s2 : s2.objectCount = " + s2.objectCount);
System.out.println("\n── Instance variables alag-alag hain ──");
System.out.println("s1.name = " + s1.name + " | s2.name = " + s2.name);
}
}
Before any object: count = 0 ✔ Object created: Rahul | Total now: 1 ✔ Object created: Amit | Total now: 2 ✔ Object created: Priya | Total now: 3 ── After 3 objects ── Class access : StaticVariable1.objectCount = 3 Via s1 : s1.objectCount = 3 Via s2 : s2.objectCount = 3 ── Instance variables alag-alag hain ── s1.name = Rahul | s2.name = Amit
class BankAccount {
// ── Static: sabhi accounts ka ek hi bank, ek hi rate ──
static String bankName = "State Bank of India";
static double interestRate = 7.5; // RBI set karta hai — sab pe laagu
// ── Instance: har account ka apna data ──
String accountHolder;
long accountNumber;
double balance;
BankAccount(String holder, long accNo, double balance) {
this.accountHolder = holder;
this.accountNumber = accNo;
this.balance = balance;
}
double calculateInterest() {
return balance * interestRate / 100; // static rate use karta hai
}
void showDetails() {
System.out.println("Bank : " + bankName); // static
System.out.println("Holder : " + accountHolder); // instance
System.out.println("Acc No : " + accountNumber); // instance
System.out.println("Balance : ₹" + balance); // instance
System.out.println("Rate : " + interestRate + "%"); // static
System.out.println("Interest : ₹" + calculateInterest());
System.out.println("─".repeat(40));
}
public static void main(String[] args) {
BankAccount a1 = new BankAccount("Rahul Sharma", 10012345L, 50000);
BankAccount a2 = new BankAccount("Priya Singh", 10067890L, 80000);
System.out.println("═══ Before Rate Change ═══");
a1.showDetails();
a2.showDetails();
// RBI ne rate change kiya → SABHI accounts affect!
System.out.println("📢 RBI ne interest rate 7.5% → 8.5% kiya!\n");
BankAccount.interestRate = 8.5; // class se change karo
System.out.println("═══ After Rate Change ═══");
a1.showDetails(); // naya rate automatically reflect
a2.showDetails(); // ← dono ek hi static variable share karte hain
}
}
═══ Before Rate Change ═══ Bank : State Bank of India Holder : Rahul Sharma Acc No : 10012345 Balance : ₹50000.0 Rate : 7.5% Interest : ₹3750.0 ──────────────────────────────────────── Bank : State Bank of India Holder : Priya Singh Acc No : 10067890 Balance : ₹80000.0 Rate : 7.5% Interest : ₹6000.0 ──────────────────────────────────────── 📢 RBI ne interest rate 7.5% → 8.5% kiya! ═══ After Rate Change ═══ Bank : State Bank of India Holder : Rahul Sharma | Rate: 8.5% | Interest: ₹4250.0 ... Bank : State Bank of India Holder : Priya Singh | Rate: 8.5% | Interest: ₹6800.0
class AppConstants {
// static final = CONSTANT — convention: ALL_CAPS naam
// Memory mein sirf ek copy, change nahi ho sakti
static final double PI = 3.14159265358979;
static final int MAX_USERS = 1000;
static final String APP_NAME = "JavaMaster";
static final String VERSION = "v2.0.1";
static final String DB_URL = "jdbc:mysql://localhost:3306/mydb";
static final double TAX_RATE = 0.18; // GST 18%
// Static mutable variable (constant nahi)
static int activeUsers = 0;
static String environment = "development";
// Static method — constant use karta hai
static double circleArea(double r) {
return PI * r * r; // constant directly use
}
static double addTax(double amount) {
return amount + (amount * TAX_RATE);
}
public static void main(String[] args) {
System.out.println("App : " + AppConstants.APP_NAME);
System.out.println("Version : " + AppConstants.VERSION);
System.out.println("DB : " + AppConstants.DB_URL);
System.out.println("Max : " + AppConstants.MAX_USERS + " users");
System.out.println("\n── Calculations ──");
System.out.printf("Circle area (r=7): %.4f%n", AppConstants.circleArea(7));
System.out.printf("Price ₹500 + GST : ₹%.2f%n", AppConstants.addTax(500));
// Mutable static
AppConstants.activeUsers = 150;
System.out.println("\nActive users: " + AppConstants.activeUsers);
// ❌ AppConstants.PI = 3.0; → COMPILE ERROR! final change nahi hota
System.out.println("\nPI = " + AppConstants.PI + " (cannot change — final!)");
}
}
App : JavaMaster Version : v2.0.1 DB : jdbc:mysql://localhost:3306/mydb Max : 1000 users ── Calculations ── Circle area (r=7): 153.9380 Price ₹500 + GST : ₹590.00 Active users: 150 PI = 3.14159265358979 (cannot change — final!)
class DatabaseConnection {
// private static — sirf ek instance store karta hai
private static DatabaseConnection instance = null;
private static int connectionCount = 0;
private String url;
private boolean connected;
// private constructor — bahar se new nahi bana sakte!
private DatabaseConnection() {
this.url = "jdbc:mysql://localhost:3306/mydb";
this.connected = true;
connectionCount++;
System.out.println("🔗 DB Connection established! [Count: " + connectionCount + "]");
}
// static factory method — getInstance
public static DatabaseConnection getInstance() {
if (instance == null) {
System.out.println("📦 Creating new connection...");
instance = new DatabaseConnection();
} else {
System.out.println("♻ Returning existing connection");
}
return instance;
}
void executeQuery(String sql) {
System.out.println("⚡ Executing: " + sql);
}
public static void main(String[] args) {
System.out.println("=== Request 1: Login ===");
DatabaseConnection db1 = DatabaseConnection.getInstance();
db1.executeQuery("SELECT * FROM users WHERE id=1");
System.out.println("\n=== Request 2: Dashboard ===");
DatabaseConnection db2 = DatabaseConnection.getInstance();
db2.executeQuery("SELECT COUNT(*) FROM orders");
System.out.println("\n=== Request 3: Profile ===");
DatabaseConnection db3 = DatabaseConnection.getInstance();
db3.executeQuery("SELECT * FROM profiles WHERE user_id=1");
System.out.println("\n── Verification ──");
System.out.println("db1 == db2? " + (db1 == db2)); // true! same object
System.out.println("db2 == db3? " + (db2 == db3)); // true!
System.out.println("Total connections created: " + connectionCount); // 1 only!
}
}
=== Request 1: Login === 📦 Creating new connection... 🔗 DB Connection established! [Count: 1] ⚡ Executing: SELECT * FROM users WHERE id=1 === Request 2: Dashboard === ♻ Returning existing connection ⚡ Executing: SELECT COUNT(*) FROM orders === Request 3: Profile === ♻ Returning existing connection ⚡ Executing: SELECT * FROM profiles WHERE user_id=1 ── Verification ── db1 == db2? true db2 == db3? true Total connections created: 1
class Vehicle {
// ── STATIC (class-level, shared) ──
static String manufacturer = "Tata Motors";
static int totalVehicles = 0;
static double averagePrice = 0;
// ── INSTANCE (object-level, individual) ──
String model;
int year;
double price;
String color;
Vehicle(String model, int year, double price, String color) {
this.model = model;
this.year = year;
this.price = price;
this.color = color;
// Static update — har naye vehicle pe
totalVehicles++;
averagePrice = ((averagePrice * (totalVehicles-1)) + price) / totalVehicles;
}
void info() {
System.out.printf(" %-10s | %d | ₹%-9.0f | %-10s | By: %s%n",
model, year, price, color, manufacturer);
}
public static void main(String[] args) {
Vehicle v1 = new Vehicle("Nexon", 2023, 900000, "Red");
Vehicle v2 = new Vehicle("Punch", 2022, 700000, "Blue");
Vehicle v3 = new Vehicle("Safari", 2024, 1800000, "White");
Vehicle v4 = new Vehicle("Harrier", 2023, 1500000, "Black");
System.out.println(" Model | Year | Price | Color | Maker");
System.out.println(" " + "─".repeat(58));
v1.info(); v2.info(); v3.info(); v4.info();
System.out.println("\n── Static Summary (Shared Data) ──");
System.out.println("Manufacturer : " + Vehicle.manufacturer);
System.out.println("Total Vehicles : " + Vehicle.totalVehicles);
System.out.printf ("Average Price : ₹%.0f%n", Vehicle.averagePrice);
// Static change → sabhi objects affect!
Vehicle.manufacturer = "Tata Motors Ltd.";
System.out.println("\nAfter name change:");
v1.info(); // updated manufacturer
v4.info(); // updated manufacturer
}
}
Model | Year | Price | Color | Maker ────────────────────────────────────────────────────────── Nexon | 2023 | ₹900000 | Red | By: Tata Motors Punch | 2022 | ₹700000 | Blue | By: Tata Motors Safari | 2024 | ₹1800000 | White | By: Tata Motors Harrier | 2023 | ₹1500000 | Black | By: Tata Motors ── Static Summary (Shared Data) ── Manufacturer : Tata Motors Total Vehicles : 4 Average Price : ₹1225000 After name change: Nexon | 2023 | ₹900000 | Red | By: Tata Motors Ltd. Harrier | 2023 | ₹1500000 | Black | By: Tata Motors Ltd.
Topic 2 — Static Method
Object banaye bina call karo — utility, factory, helper patterns
Static method woh method hai jo class ke saath belong karta hai, kisi particular object ke saath nahi. Ise call karne ke liye object create karne ki zaroorat nahi — sirf class name use karo: ClassName.methodName().
Static method ke rules (bahut important!):
- ✅ Static method → static variable access kar sakta hai
- ✅ Static method → doosre static method ko call kar sakta hai
- ❌ Static method → instance variable directly access nahi kar sakta
- ❌ Static method → instance method call nahi kar sakta (directly)
- ❌ Static method →
thiskeyword use nahi kar sakta
Kyun? Kyunki static method tab bhi exist karta hai jab koi object nahi hota. Agar koi object hi nahi hai toh "this" ka kya matlab? Isliye static method object-specific cheezein access nahi kar sakta.
main() static kyun hai? JVM program start karte waqt koi object nahi banata. Isliye main() static hona chahiye taaki JVM directly ClassName.main(args) call kar sake.
Kab use karein? Utility/helper operations ke liye — Math.sqrt(), Integer.parseInt(), Arrays.sort() — ye sab static methods hain! Jab method ko kisi particular object ke state ki zaroorat nahi ho.
✅ Static Method Kar Sakta Hai
- Static variables read/write karna
- Doosre static methods call karna
- Local variables use karna
- Objects create karke unka use karna
- Parameters lena aur return karna
- synchronized hona (class-level lock)
❌ Static Method Nahi Kar Sakta
- Instance variables directly access karna
- Instance methods directly call karna
thiskeyword use karnasuperkeyword use karna- Override hona (sirf hide hota hai)
- Abstract hona
public class StaticMethodBasics {
static int count = 0; // static — class level
String name; // instance — object level
StaticMethodBasics(String name) {
this.name = name;
count++;
}
// ── Static Method ──
static void showCount() {
System.out.println("Objects created: " + count); // ✅ static access
// name = "test"; ← COMPILE ERROR! instance var nahi
// greet(); ← COMPILE ERROR! instance method nahi
}
static int add(int a, int b) { return a + b; }
static boolean isPositive(int n) { return n > 0; }
static String repeat(String s, int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) sb.append(s);
return sb.toString();
}
// ── Instance Method ── (object chahiye)
void greet() {
// instance method: dono access kar sakta hai
System.out.println("Hello from " + name + " | Total: " + count);
showCount(); // ✅ instance method static ko call kar sakta hai
}
public static void main(String[] args) {
// Object banaye bina static call!
StaticMethodBasics.showCount();
System.out.println("add(10,5) = " + add(10, 5));
System.out.println("isPositive(-3) = " + isPositive(-3));
System.out.println("repeat(\"Ha\",3) = " + repeat("Ha", 3));
// Objects banao
StaticMethodBasics s1 = new StaticMethodBasics("Rahul");
StaticMethodBasics s2 = new StaticMethodBasics("Priya");
s1.greet();
s2.greet();
showCount(); // 2
}
}
Objects created: 0
add(10,5) = 15
isPositive(-3) = false
repeat("Ha",3) = HaHaHa
Hello from Rahul | Total: 1
Objects created: 1
Hello from Priya | Total: 2
Objects created: 2
Objects created: 2
class MathUtils {
// Private constructor — object banana allowed nahi!
// Ye pure utility class hai, sirf static methods ke liye
private MathUtils() {
throw new UnsupportedOperationException("Utility class!");
}
static int abs(int n) { return n < 0 ? -n : n; }
static double power(double b, int e) {
double r = 1;
for (int i = 0; i < e; i++) r *= b;
return r;
}
static boolean isPrime(int n) {
if (n < 2) return false;
for (int i = 2; i * i <= n; i++)
if (n % i == 0) return false;
return true;
}
static int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1); // recursive static!
}
static int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
static int lcm(int a, int b) { return a / gcd(a, b) * b; }
static double percentage(double val, double total) { return (val / total) * 100; }
static int clamp(int val, int min, int max) {
return Math.max(min, Math.min(max, val));
}
public static void main(String[] args) {
// Koi object nahi! Seedha class name se:
System.out.println("abs(-42) = " + MathUtils.abs(-42));
System.out.println("power(2,10) = " + MathUtils.power(2, 10));
System.out.println("factorial(7) = " + MathUtils.factorial(7));
System.out.println("isPrime(97) = " + MathUtils.isPrime(97));
System.out.println("isPrime(100) = " + MathUtils.isPrime(100));
System.out.println("gcd(48,18) = " + MathUtils.gcd(48, 18));
System.out.println("lcm(4,6) = " + MathUtils.lcm(4, 6));
System.out.println("percentage(45,60)= " + MathUtils.percentage(45, 60) + "%");
System.out.println("clamp(150,0,100) = " + MathUtils.clamp(150, 0, 100));
}
}
abs(-42) = 42 power(2,10) = 1024.0 factorial(7) = 5040 isPrime(97) = true isPrime(100) = false gcd(48,18) = 6 lcm(4,6) = 12 percentage(45,60)= 75.0% clamp(150,0,100) = 100
class User {
private String username;
private String email;
private String role;
private boolean active;
// Private constructor — sirf class ke andar se call hoga
private User(String username, String email, String role) {
this.username = username;
this.email = email;
this.role = role;
this.active = true;
System.out.println("✔ Created [" + role + "] user: " + username);
}
// ── Static Factory Methods ──
// Naam se clear hai kya ban raha hai — constructor se better!
static User createAdmin(String username, String email) {
return new User(username, email, "ADMIN");
}
static User createCustomer(String username, String email) {
return new User(username, email, "CUSTOMER");
}
static User createModerator(String username, String email) {
return new User(username, email, "MODERATOR");
}
static User createGuest() {
String tempName = "guest_" + System.currentTimeMillis() % 10000;
return new User(tempName, tempName + "@temp.com", "GUEST");
}
// Static validation method
static boolean isValidEmail(String email) {
return email != null
&& email.contains("@")
&& email.indexOf("@") > 0
&& email.contains(".");
}
static boolean isValidUsername(String u) {
return u != null && u.length() >= 4 && u.matches("[a-zA-Z0-9_]+");
}
void display() {
System.out.printf(" User: %-15s | Role: %-10s | Active: %b%n",
username, role, active);
}
public static void main(String[] args) {
System.out.println("── Validation First ──");
String email = "rahul@company.com";
System.out.println("Email valid? " + isValidEmail(email));
System.out.println("Username valid? " + isValidUsername("rk")); // false (too short)
System.out.println("Username valid? " + isValidUsername("rahul")); // true
System.out.println("\n── Creating Users ──");
User admin = User.createAdmin("superadmin", "admin@company.com");
User cust = User.createCustomer("rahul_k", "rahul@gmail.com");
User mod = User.createModerator("mod_priya", "priya@company.com");
User guest = User.createGuest();
System.out.println("\n── User List ──");
admin.display(); cust.display(); mod.display(); guest.display();
}
}
── Validation First ── Email valid? true Username valid? false Username valid? true ── Creating Users ── ✔ Created [ADMIN] user: superadmin ✔ Created [CUSTOMER] user: rahul_k ✔ Created [MODERATOR] user: mod_priya ✔ Created [GUEST] user: guest_7342 ── User List ── User: superadmin | Role: ADMIN | Active: true User: rahul_k | Role: CUSTOMER | Active: true User: mod_priya | Role: MODERATOR | Active: true User: guest_7342 | Role: GUEST | Active: true
class StringUtils {
private StringUtils() {} // utility class — no instances
// Reverse a string
static String reverse(String s) {
return new StringBuilder(s).reverse().toString();
}
// Check palindrome
static boolean isPalindrome(String s) {
s = s.toLowerCase().replaceAll("[^a-z0-9]", "");
return s.equals(reverse(s));
}
// Count occurrences of a character
static int countChar(String s, char c) {
int count = 0;
for (char ch : s.toCharArray()) if (ch == c) count++;
return count;
}
// Capitalize first letter of each word
static String titleCase(String s) {
String[] words = s.toLowerCase().split(" ");
StringBuilder sb = new StringBuilder();
for (String w : words)
sb.append(Character.toUpperCase(w.charAt(0))).append(w.substring(1)).append(" ");
return sb.toString().trim();
}
// Mask sensitive data (e.g., email, phone)
static String maskEmail(String email) {
int at = email.indexOf('@');
if (at < 2) return "***@" + email.substring(at + 1);
return email.charAt(0) + "*".repeat(at - 2) + email.charAt(at-1) + email.substring(at);
}
static String maskPhone(String phone) {
return phone.substring(0, 2) + "****" + phone.substring(6);
}
// Truncate with ellipsis
static String truncate(String s, int maxLen) {
return s.length() <= maxLen ? s : s.substring(0, maxLen - 3) + "...";
}
public static void main(String[] args) {
System.out.println("reverse('Hello') = " + StringUtils.reverse("Hello"));
System.out.println("isPalindrome('racecar') = " + StringUtils.isPalindrome("racecar"));
System.out.println("isPalindrome('A man a plan a canal Panama') = "
+ StringUtils.isPalindrome("A man a plan a canal Panama"));
System.out.println("countChar('banana','a') = " + StringUtils.countChar("banana", 'a'));
System.out.println("titleCase('hello world java') = "
+ StringUtils.titleCase("hello world java"));
System.out.println("maskEmail('rahul@gmail.com') = "
+ StringUtils.maskEmail("rahul@gmail.com"));
System.out.println("maskPhone('9876543210') = "
+ StringUtils.maskPhone("9876543210"));
System.out.println("truncate('Hello World Java',10) = "
+ StringUtils.truncate("Hello World Java", 10));
}
}
reverse('Hello') = olleH
isPalindrome('racecar') = true
isPalindrome('A man a plan a canal Panama') = true
countChar('banana','a') = 3
titleCase('hello world java') = Hello World Java
maskEmail('rahul@gmail.com') = r***l@gmail.com
maskPhone('9876543210') = 98****3210
truncate('Hello World Java',10) = Hello W...
public class WhyMainIsStatic {
static String appName = "JavaApp";
int instanceId;
static int nextId = 0;
WhyMainIsStatic() {
instanceId = ++nextId;
showBanner(); // constructor mein static method call kar sakte hain ✅
}
// Static method calling another static
static void showBanner() {
System.out.println("╔══════════════════════════╗");
System.out.println("║ " + appName + " - Starting Up ║");
System.out.println("╚══════════════════════════╝");
}
// Static method — calculations
static int doubleIt(int n) { return multiply(n, 2); } // static → static ✅
static int multiply(int a, int b) { return a * b; }
// Instance method
void showInstanceInfo() {
// Instance method can access both
System.out.println("Instance #" + instanceId + " of " + appName);
showBanner(); // instance method → static method ✅
}
public static void main(String[] args) {
/*
* JVM karta hai: WhyMainIsStatic.main(args)
* JVM ne koi object nahi banaya!
* Isliye main() MUST be static — object ke bina call hona chahiye.
*
* Agar main() non-static hoti:
* JVM ko pehle WhyMainIsStatic obj = new WhyMainIsStatic() banana padta
* Lekin fir constructor call hota, aur object kaun banata? — Chicken-egg problem!
*/
System.out.println("JVM ne main() directly call kiya — no object created yet!");
System.out.println("appName = " + appName); // static variable ✅
// Instance methods call karna ho toh object banana padega
WhyMainIsStatic obj1 = new WhyMainIsStatic();
WhyMainIsStatic obj2 = new WhyMainIsStatic();
obj1.showInstanceInfo();
obj2.showInstanceInfo();
System.out.println("\ndoubleIt(7) = " + doubleIt(7)); // static → static ✅
System.out.println("nextId = " + nextId); // static var ✅
}
}
JVM ne main() directly call kiya — no object created yet! appName = JavaApp ╔══════════════════════════╗ ║ JavaApp - Starting Up ║ ╚══════════════════════════╝ ╔══════════════════════════╗ ║ JavaApp - Starting Up ║ ╚══════════════════════════╝ Instance #1 of JavaApp JavaApp banner... Instance #2 of JavaApp JavaApp banner... doubleIt(7) = 14 nextId = 2
Topic 3 — Static Block (Static Initializer)
Class load pe sirf ek baar — initialization logic ka perfect jagah
Static block (ya Static Initializer Block) ek code block hai jo class mein static { } ke andar likha jaata hai. Yeh tab execute hota hai jab JVM class ko pehli baar load karta hai — aur sirf ek hi baar execute hota hai, chahe baad mein 100 objects banao.
Static block kab use karein?
- Complex initialization: Jab static variable ko simple assignment se zyada complex logic se initialize karna ho
- Exception handling: Static variable initialization mein exception handle karni ho (jo simple assignment mein possible nahi)
- Configuration loading: Database config, properties file, drivers load karna
- Lookup tables: Maps, arrays ko pre-populate karna
Execution Order (bahut important!):
- Static variables default values se initialize hote hain
- Static variables aur blocks top-to-bottom order mein execute hote hain
- Constructor execute hota hai (har object ke liye)
public class StaticBlockBasic {
static int x;
static int y;
static String message;
// Static block — class load hote waqt SIRF EK BAAR
static {
System.out.println("══ Static Block Executing ══");
x = 100;
y = 200;
message = "Initialized in static block";
System.out.println("x=" + x + ", y=" + y);
System.out.println("Static block DONE!\n");
}
int instanceVar;
// Constructor — har object ke liye
StaticBlockBasic(int val) {
this.instanceVar = val;
System.out.println("Constructor called! instanceVar=" + val
+ " | x=" + x + " (static)");
}
public static void main(String[] args) {
System.out.println("main() start\n"); // Note: static block already ran!
System.out.println("Creating object 1:");
StaticBlockBasic obj1 = new StaticBlockBasic(10);
System.out.println("\nCreating object 2:");
StaticBlockBasic obj2 = new StaticBlockBasic(20);
System.out.println("\nCreating object 3:");
StaticBlockBasic obj3 = new StaticBlockBasic(30);
System.out.println("\nFinal: x=" + x + " | message=" + message);
System.out.println("Note: Static block ran only ONCE, constructor ran 3 times!");
}
}
══ Static Block Executing ══ x=100, y=200 Static block DONE! main() start Creating object 1: Constructor called! instanceVar=10 | x=100 (static) Creating object 2: Constructor called! instanceVar=20 | x=100 (static) Creating object 3: Constructor called! instanceVar=30 | x=100 (static) Final: x=100 | message=Initialized in static block Note: Static block ran only ONCE, constructor ran 3 times!
public class MultipleStaticBlocks {
// Variables and blocks execute in TOP-TO-BOTTOM order
static int a = initA(); // method call for initialization
static {
System.out.println("Static Block #1: a=" + a);
a = a * 2; // a was 5, now 10
System.out.println("Static Block #1 end: a=" + a);
}
static int b = a + 5; // b = 10+5 = 15 (after block #1)
static {
System.out.println("Static Block #2: a=" + a + ", b=" + b);
b = b * 2; // b = 30
System.out.println("Static Block #2 end: b=" + b);
}
static int c = a + b; // c = 10+30 = 40 (after both blocks)
// Static method used for initialization
static int initA() {
System.out.println("initA() called — a initializing to 5");
return 5;
}
public static void main(String[] args) {
System.out.println("\n── main() executing ──");
System.out.println("a = " + a); // 10
System.out.println("b = " + b); // 30
System.out.println("c = " + c); // 40
System.out.println("\nConclusion: Execution order = top to bottom!");
}
}
initA() called — a initializing to 5 Static Block #1: a=5 Static Block #1 end: a=10 Static Block #2: a=10, b=15 Static Block #2 end: b=30 ── main() executing ── a = 10 b = 30 c = 40 Conclusion: Execution order = top to bottom!
class AppConfig {
// final constants — static block se initialize karenge
static final String DB_HOST;
static final int DB_PORT;
static final String DB_NAME;
static final int POOL_SIZE;
static final String LOG_LEVEL;
static final String BASE_URL;
static boolean configLoaded = false;
// Static block: real world mein environment variables ya properties file se padha jaata
static {
System.out.println("[BOOT] Loading application configuration...");
try {
// Simulate: properties file / env variables read karna
DB_HOST = System.getenv("DB_HOST") != null ? System.getenv("DB_HOST") : "localhost";
DB_PORT = 3306;
DB_NAME = "backend_app";
POOL_SIZE = 10;
LOG_LEVEL = "INFO";
BASE_URL = "https://api.myapp.com/v1";
configLoaded = true;
System.out.println("[BOOT] ✔ DB_HOST : " + DB_HOST);
System.out.println("[BOOT] ✔ DB_PORT : " + DB_PORT);
System.out.println("[BOOT] ✔ DB_NAME : " + DB_NAME);
System.out.println("[BOOT] ✔ POOL_SIZE : " + POOL_SIZE);
System.out.println("[BOOT] ✔ LOG_LEVEL : " + LOG_LEVEL);
System.out.println("[BOOT] ✔ BASE_URL : " + BASE_URL);
System.out.println("[BOOT] Configuration loaded successfully!\n");
} catch (Exception e) {
// Static block mein exception handle kar sakte hain!
throw new RuntimeException("Config loading failed: " + e.getMessage());
}
}
static String getConnectionString() {
return "jdbc:mysql://" + DB_HOST + ":" + DB_PORT + "/" + DB_NAME;
}
public static void main(String[] args) {
System.out.println("[APP] Application starting...");
System.out.println("[APP] Config loaded: " + configLoaded);
System.out.println("[APP] Connection : " + AppConfig.getConnectionString());
System.out.println("[APP] API Base : " + AppConfig.BASE_URL);
System.out.println("[APP] Pool size : " + AppConfig.POOL_SIZE);
}
}
[BOOT] Loading application configuration... [BOOT] ✔ DB_HOST : localhost [BOOT] ✔ DB_PORT : 3306 [BOOT] ✔ DB_NAME : backend_app [BOOT] ✔ POOL_SIZE : 10 [BOOT] ✔ LOG_LEVEL : INFO [BOOT] ✔ BASE_URL : https://api.myapp.com/v1 [BOOT] Configuration loaded successfully! [APP] Application starting... [APP] Config loaded: true [APP] Connection : jdbc:mysql://localhost:3306/backend_app [APP] API Base : https://api.myapp.com/v1 [APP] Pool size : 10
class LifecycleDemo {
static int staticVar = 0;
int instanceVar;
static int objectNumber = 0;
// 1. Static block — class load pe ONCE
static {
staticVar = 100;
System.out.println("1️⃣ STATIC BLOCK runs ONCE | staticVar=" + staticVar);
}
// 2. Instance initializer block — har object ke liye (constructor se pehle)
{
objectNumber++;
System.out.println("2️⃣ INSTANCE INIT BLOCK | object #" + objectNumber);
instanceVar = staticVar + objectNumber; // uses static var
}
// 3. Constructor — har object ke liye (instance block ke baad)
LifecycleDemo(String name) {
System.out.println("3️⃣ CONSTRUCTOR | " + name
+ " | instanceVar=" + instanceVar + "\n");
}
public static void main(String[] args) {
System.out.println("━━━ Creating Object 1 ━━━");
LifecycleDemo o1 = new LifecycleDemo("First");
System.out.println("━━━ Creating Object 2 ━━━");
LifecycleDemo o2 = new LifecycleDemo("Second");
System.out.println("━━━ Creating Object 3 ━━━");
LifecycleDemo o3 = new LifecycleDemo("Third");
System.out.println("━━━ Final State ━━━");
System.out.println("staticVar = " + staticVar);
System.out.println("o1.instanceVar = " + o1.instanceVar);
System.out.println("o2.instanceVar = " + o2.instanceVar);
System.out.println("o3.instanceVar = " + o3.instanceVar);
}
}
━━━ Creating Object 1 ━━━ 1️⃣ STATIC BLOCK runs ONCE | staticVar=100 2️⃣ INSTANCE INIT BLOCK | object #1 3️⃣ CONSTRUCTOR | First | instanceVar=101 ━━━ Creating Object 2 ━━━ 2️⃣ INSTANCE INIT BLOCK | object #2 3️⃣ CONSTRUCTOR | Second | instanceVar=102 ━━━ Creating Object 3 ━━━ 2️⃣ INSTANCE INIT BLOCK | object #3 3️⃣ CONSTRUCTOR | Third | instanceVar=103 ━━━ Final State ━━━ staticVar = 100 o1.instanceVar = 101 o2.instanceVar = 102 o3.instanceVar = 103
import java.util.*;
class CountryDatabase {
// Static maps — once initialize, always available
private static final Map<String, String> COUNTRY_CODES = new HashMap<>();
private static final Map<String, String> CURRENCIES = new HashMap<>();
private static final Map<String, Integer> DIAL_CODES = new HashMap<>();
private static int entryCount = 0;
// Static block: data load karo — database/file ki tarah
static {
System.out.println("[DB] Loading country database...");
// Country code → Country name
COUNTRY_CODES.put("IN", "India");
COUNTRY_CODES.put("US", "United States");
COUNTRY_CODES.put("GB", "United Kingdom");
COUNTRY_CODES.put("JP", "Japan");
COUNTRY_CODES.put("DE", "Germany");
COUNTRY_CODES.put("AU", "Australia");
// Country code → Currency
CURRENCIES.put("IN", "INR - Indian Rupee");
CURRENCIES.put("US", "USD - US Dollar");
CURRENCIES.put("GB", "GBP - British Pound");
CURRENCIES.put("JP", "JPY - Japanese Yen");
CURRENCIES.put("DE", "EUR - Euro");
CURRENCIES.put("AU", "AUD - Australian Dollar");
// Country code → Dial code
DIAL_CODES.put("IN", 91); DIAL_CODES.put("US", 1);
DIAL_CODES.put("GB", 44); DIAL_CODES.put("JP", 81);
DIAL_CODES.put("DE", 49); DIAL_CODES.put("AU", 61);
entryCount = COUNTRY_CODES.size();
System.out.println("[DB] Loaded " + entryCount + " countries successfully!\n");
}
// Static lookup methods — no object needed!
static String getCountry(String code) { return COUNTRY_CODES.getOrDefault(code, "Unknown"); }
static String getCurrency(String code) { return CURRENCIES.getOrDefault(code, "Unknown"); }
static int getDialCode(String code) { return DIAL_CODES.getOrDefault(code, 0); }
static void lookup(String code) {
System.out.printf("Code: %-4s | Country: %-20s | Currency: %-25s | Dial: +%d%n",
code, getCountry(code), getCurrency(code), getDialCode(code));
}
public static void main(String[] args) {
String[] codes = {"IN", "US", "GB", "JP", "DE", "AU", "XY"};
System.out.println("Country Lookup Results:");
System.out.println("─".repeat(75));
for (String code : codes) lookup(code);
System.out.println("\nTotal entries: " + entryCount);
}
}
[DB] Loading country database... [DB] Loaded 6 countries successfully! Country Lookup Results: ─────────────────────────────────────────────────────────────────────────── Code: IN | Country: India | Currency: INR - Indian Rupee | Dial: +91 Code: US | Country: United States | Currency: USD - US Dollar | Dial: +1 Code: GB | Country: United Kingdom | Currency: GBP - British Pound | Dial: +44 Code: JP | Country: Japan | Currency: JPY - Japanese Yen | Dial: +81 Code: DE | Country: Germany | Currency: EUR - Euro | Dial: +49 Code: AU | Country: Australia | Currency: AUD - Australian Dollar | Dial: +61 Code: XY | Country: Unknown | Currency: Unknown | Dial: +0 Total entries: 6
Topic 4 — Static Nested Class
Outer object ke bina nested class — Builder, Node, Helper patterns
Java mein ek class ke andar doosri class define kar sakte hain — ise nested class kehte hain. Nested classes 4 types ki hoti hain: Static Nested, Inner (non-static), Local, aur Anonymous. Aaj ka topic hai Static Nested Class.
Static Nested Class ke characteristics:
- Independent existence: Outer class ke object ki zaroorat nahi — directly instantiate ho sakti hai
- Access restriction: Outer class ke sirf static members access kar sakti hai (non-static instance members nahi)
- Logically grouped: Outer class ke saath logically related hai isliye andar rakha, lekin tightly coupled nahi hai
- No outer reference: Inner class ki tarah outer object ka hidden reference nahi hota — memory efficient
Inner Class (non-static) se fark: Inner class ke object banane ke liye pehle outer class ka object banana padta hai (outerObj.new Inner()). Static nested class mein aisa nahi — sirf new Outer.Nested() likhna hoga.
Real-world use cases: Builder pattern (Lombok @Builder ke andar), LinkedList Node, Tree Node, HTTP Request/Response models, API Response wrappers.
public class NestedClassDemo {
private static int outerStatic = 100;
private int outerInstance = 200;
// ── STATIC NESTED CLASS ──
static class StaticNested {
int nestedVar = 50;
void display() {
System.out.println("StaticNested.display()");
System.out.println(" outerStatic = " + outerStatic); // ✅ static access
// outerInstance = ??? ← COMPILE ERROR
System.out.println(" nestedVar = " + nestedVar);
}
void compute(int x) {
System.out.println(" outerStatic * x = " + (outerStatic * x));
}
}
// ── INNER CLASS (non-static) ──
class Inner {
void display() {
System.out.println("Inner.display()");
System.out.println(" outerStatic = " + outerStatic); // ✅
System.out.println(" outerInstance = " + outerInstance); // ✅ both access
}
}
public static void main(String[] args) {
System.out.println("── Static Nested (no outer object needed) ──");
NestedClassDemo.StaticNested nested = new NestedClassDemo.StaticNested();
nested.display();
nested.compute(5);
System.out.println("\n── Inner Class (outer object required) ──");
NestedClassDemo outer = new NestedClassDemo();
NestedClassDemo.Inner inner = outer.new Inner();
inner.display();
System.out.println("\n── Summary ──");
System.out.println("Static Nested: new Outer.Nested() — independent");
System.out.println("Inner Class : outerObj.new Inner() — needs outer");
}
}
── Static Nested (no outer object needed) ── StaticNested.display() outerStatic = 100 nestedVar = 50 outerStatic * x = 500 ── Inner Class (outer object required) ── Inner.display() outerStatic = 100 outerInstance = 200 ── Summary ── Static Nested: new Outer.Nested() — independent Inner Class : outerObj.new Inner() — needs outer
class Product {
// All fields — private, set only via Builder
private final String name;
private final String category;
private final double price;
private final int quantity;
private final String sku;
private final boolean inStock;
// Private constructor — sirf Builder banayega
private Product(Builder b) {
this.name = b.name;
this.category = b.category;
this.price = b.price;
this.quantity = b.quantity;
this.sku = b.sku;
this.inStock = b.quantity > 0;
}
// ★ STATIC NESTED BUILDER CLASS ★
static class Builder {
// Required
private String name;
// Optional (with defaults)
private String category = "General";
private double price = 0.0;
private int quantity = 0;
private String sku = "SKU-" + System.currentTimeMillis() % 1000;
Builder(String name) { this.name = name; }
// Fluent setters — each returns Builder for chaining
Builder category(String c) { this.category = c; return this; }
Builder price(double p) { this.price = p; return this; }
Builder quantity(int q) { this.quantity = q; return this; }
Builder sku(String s) { this.sku = s; return this; }
// Validation before building
Product build() {
if (name == null || name.isEmpty())
throw new IllegalStateException("Product name required!");
if (price < 0)
throw new IllegalStateException("Price cannot be negative!");
return new Product(this);
}
}
void display() {
System.out.println("━━━ " + name + " ━━━");
System.out.println(" SKU : " + sku);
System.out.println(" Category : " + category);
System.out.printf (" Price : ₹%.2f%n", price);
System.out.println(" Quantity : " + quantity);
System.out.println(" In Stock : " + (inStock ? "✔ Yes" : "✘ Out of Stock"));
}
public static void main(String[] args) {
// Fluent builder — readable, no constructor hell!
Product p1 = new Product.Builder("MacBook Pro")
.category("Electronics")
.price(125000)
.quantity(15)
.sku("ELEC-001")
.build();
Product p2 = new Product.Builder("Java Programming Book")
.category("Books")
.price(599)
.quantity(0) // out of stock
.sku("BOOK-042")
.build();
// Minimal — just name (optional fields default pe)
Product p3 = new Product.Builder("Sample Item").build();
p1.display(); System.out.println();
p2.display(); System.out.println();
p3.display();
}
}
━━━ MacBook Pro ━━━ SKU : ELEC-001 Category : Electronics Price : ₹125000.00 Quantity : 15 In Stock : ✔ Yes ━━━ Java Programming Book ━━━ SKU : BOOK-042 Category : Books Price : ₹599.00 Quantity : 0 In Stock : ✘ Out of Stock ━━━ Sample Item ━━━ SKU : SKU-892 Category : General Price : ₹0.00 Quantity : 0 In Stock : ✘ Out of Stock
public class MyLinkedList {
// ★ Static Nested Node — outer object nahi chahiye
static class Node {
int data;
Node next;
Node(int data) { this.data = data; this.next = null; }
}
private Node head = null;
private int size = 0;
void addFirst(int val) {
Node n = new Node(val); // No outer object — just new Node()
n.next = head;
head = n;
size++;
}
void addLast(int val) {
Node n = new Node(val);
if (head == null) { head = n; size++; return; }
Node cur = head;
while (cur.next != null) cur = cur.next;
cur.next = n;
size++;
}
boolean removeFirst() {
if (head == null) return false;
head = head.next;
size--;
return true;
}
int sum() {
int total = 0;
Node cur = head;
while (cur != null) { total += cur.data; cur = cur.next; }
return total;
}
void reverse() {
Node prev = null, curr = head, next;
while (curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
head = prev;
}
void print(String label) {
System.out.print(label + ": ");
Node cur = head;
while (cur != null) {
System.out.print(cur.data + (cur.next != null ? " → " : ""));
cur = cur.next;
}
System.out.println(" | size=" + size + " | sum=" + sum());
}
public static void main(String[] args) {
MyLinkedList list = new MyLinkedList();
list.addLast(10); list.addLast(20); list.addLast(30);
list.addFirst(5); list.addLast(40);
list.print("Original ");
list.reverse();
list.print("Reversed ");
list.removeFirst();
list.print("After del");
// Node can be used standalone — no MyLinkedList needed!
MyLinkedList.Node standalone = new MyLinkedList.Node(999);
System.out.println("\nStandalone node: " + standalone.data);
}
}
Original : 5 → 10 → 20 → 30 → 40 | size=5 | sum=105 Reversed : 40 → 30 → 20 → 10 → 5 | size=5 | sum=105 After del: 30 → 20 → 10 → 5 | size=4 | sum=65 Standalone node: 999
public class ApiResponse {
private int status;
private String message;
private Object data;
private boolean success;
private long timestamp;
private ApiResponse(int status, String message, Object data, boolean success) {
this.status = status;
this.message = message;
this.data = data;
this.success = success;
this.timestamp = System.currentTimeMillis();
}
// Static factory methods
static ApiResponse ok(Object data) { return new ApiResponse(200, "Success", data, true); }
static ApiResponse created(Object data) { return new ApiResponse(201, "Created", data, true); }
static ApiResponse notFound(String msg) { return new ApiResponse(404, msg, null, false); }
static ApiResponse badRequest(String msg) { return new ApiResponse(400, msg, null, false); }
static ApiResponse serverError(String msg) { return new ApiResponse(500, msg, null, false); }
// ★ Static Nested DTOs ★
static class UserDTO {
String id, name, email, role;
UserDTO(String id, String name, String email, String role) {
this.id=id; this.name=name; this.email=email; this.role=role;
}
public String toString() {
return "{id:"+id+", name:"+name+", email:"+email+", role:"+role+"}";
}
}
static class PagedResult {
Object[] items;
int page, totalPages, totalCount;
PagedResult(Object[] items, int page, int totalPages, int total) {
this.items=items; this.page=page; this.totalPages=totalPages; this.totalCount=total;
}
public String toString() {
return "{page:"+page+"/"+totalPages+", total:"+totalCount+", items:"+items.length+"}";
}
}
void print() {
System.out.println("{");
System.out.println(" status : " + status);
System.out.println(" success : " + success);
System.out.println(" message : \"" + message + "\"");
System.out.println(" data : " + data);
System.out.println("}");
}
public static void main(String[] args) {
ApiResponse.UserDTO user = new ApiResponse.UserDTO("U001","Rahul","rahul@g.com","ADMIN");
System.out.println("GET /api/users/U001");
ApiResponse.ok(user).print();
System.out.println("\nPOST /api/users");
ApiResponse.created(user).print();
System.out.println("\nGET /api/users/XYZ");
ApiResponse.notFound("User not found with id: XYZ").print();
ApiResponse.UserDTO[] users = {
new ApiResponse.UserDTO("U001","Rahul","r@g.com","ADMIN"),
new ApiResponse.UserDTO("U002","Priya","p@g.com","USER")
};
ApiResponse.PagedResult paged = new ApiResponse.PagedResult(users, 1, 5, 47);
System.out.println("\nGET /api/users?page=1");
ApiResponse.ok(paged).print();
}
}
GET /api/users/U001
{
status : 200
success : true
message : "Success"
data : {id:U001, name:Rahul, email:rahul@g.com, role:ADMIN}
}
POST /api/users
{
status : 201
success : true
message : "Created"
data : {id:U001, name:Rahul, email:rahul@g.com, role:ADMIN}
}
GET /api/users/XYZ
{
status : 404
success : false
message : "User not found with id: XYZ"
data : null
}
GET /api/users?page=1
{
status : 200
success : true
message : "Success"
data : {page:1/5, total:47, items:2}
}
Topic 5 — Static Import
Class name likhne ki zaroorat nahi — directly static members use karo
Static import Java 5 mein introduce hua. Isse aap kisi class ke static members (variables aur methods) ko directly use kar sakte ho — class name likhne ki zaroorat nahi padti.
Syntax:
import static java.lang.Math.PI;— sirf PI importimport static java.lang.Math.*;— Math ke sab static membersimport static java.lang.System.out;— System.out ko out se use karo
Kab use karein:
- Scientific calculations jahan Math. baar baar likhna repetitive lage
- JUnit testing mein —
import static org.junit.Assert.*; - Constants heavy code — AppConstants.MAX baar baar likhne ki jagah
Kab avoid karein:
- Jab do alag classes mein same naam ka static member ho — ambiguity aayegi
- Jab code padh kar samajh na aaye ki method kahan se aaya — readability hurt hoti hai
- Overuse mat karo —
Math.sqrt()zyada readable hai sirfsqrt()se
import static java.lang.Math.*;
import static java.lang.System.out;
public class StaticImportMath {
// Custom methods using static imported names directly
static double circleArea(double r) { return PI * r * r; }
static double hypotenuse(double a, double b){ return sqrt(a*a + b*b); }
static double degToRad(double d) { return d * PI / 180.0; }
public static void main(String[] args) {
out.println("── Math Constants ──");
out.println("PI = " + PI); // Math.PI
out.println("E = " + E); // Math.E
out.println("\n── Common Operations ──");
out.println("sqrt(144) = " + sqrt(144)); // Math.sqrt
out.println("pow(2,10) = " + pow(2, 10)); // Math.pow
out.println("abs(-99) = " + abs(-99)); // Math.abs
out.println("ceil(4.1) = " + ceil(4.1)); // Math.ceil
out.println("floor(4.9) = " + floor(4.9)); // Math.floor
out.println("round(4.5) = " + round(4.5)); // Math.round
out.println("max(17,42) = " + max(17, 42)); // Math.max
out.println("log(E) = " + log(E)); // Math.log
out.println("\n── Geometry ──");
out.printf("circleArea(r=5) = %.4f%n", circleArea(5));
out.printf("hypotenuse(3,4) = %.1f%n", hypotenuse(3, 4));
out.println("\n── Trigonometry ──");
double[] degs = {0, 30, 45, 60, 90};
for (double d : degs) {
out.printf("sin(%2.0f°)=%.4f cos(%2.0f°)=%.4f%n",
d, sin(degToRad(d)), d, cos(degToRad(d)));
}
}
}
── Math Constants ── PI = 3.141592653589793 E = 2.718281828459045 ── Common Operations ── sqrt(144) = 12.0 pow(2,10) = 1024.0 abs(-99) = 99 ceil(4.1) = 5.0 floor(4.9) = 4.0 round(4.5) = 5 max(17,42) = 42 log(E) = 1.0 ── Geometry ── circleArea(r=5) = 78.5398 hypotenuse(3,4) = 5.0 ── Trigonometry ── sin( 0°)=0.0000 cos( 0°)=1.0000 sin(30°)=0.5000 cos(30°)=0.8660 sin(45°)=0.7071 cos(45°)=0.7071 sin(60°)=0.8660 cos(60°)=0.5000 sin(90°)=1.0000 cos(90°)=0.0000
import static java.lang.System.out;
import static java.lang.System.err;
import static java.util.Arrays.sort;
import static java.util.Arrays.fill;
import static java.util.Arrays.copyOf;
import static java.util.Arrays.copyOfRange;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.toString;
public class StaticImportArrays {
public static void main(String[] args) {
int[] arr = {5, 2, 8, 1, 9, 3, 7, 4, 6};
out.println("Original : " + toString(arr)); // Arrays.toString
sort(arr); // Arrays.sort
out.println("Sorted : " + toString(arr));
// binarySearch — array must be sorted
int idx = binarySearch(arr, 7); // Arrays.binarySearch
out.println("Index of 7: " + idx);
// copyOf — first n elements
int[] first5 = copyOf(arr, 5); // Arrays.copyOf
out.println("First 5 : " + toString(first5));
// copyOfRange — slice
int[] mid = copyOfRange(arr, 2, 6); // Arrays.copyOfRange
out.println("Index 2-5: " + toString(mid));
// fill — all same value
int[] zeros = new int[5];
fill(zeros, 0); // Arrays.fill
out.println("Filled 0s: " + toString(zeros));
fill(zeros, 99);
out.println("Filled 99: " + toString(zeros));
// err — System.err (stderr stream)
err.println("[ERR] This is error stream output");
}
}
Original : [5, 2, 8, 1, 9, 3, 7, 4, 6] Sorted : [1, 2, 3, 4, 5, 6, 7, 8, 9] Index of 7: 6 First 5 : [1, 2, 3, 4, 5] Index 2-5: [3, 4, 5, 6] Filled 0s: [0, 0, 0, 0, 0] Filled 99: [99, 99, 99, 99, 99] [ERR] This is error stream output
// Constants class — same package mein ho toh import karo
class HttpCode {
static final int OK = 200;
static final int CREATED = 201;
static final int NO_CONTENT = 204;
static final int BAD_REQUEST = 400;
static final int UNAUTHORIZED = 401;
static final int NOT_FOUND = 404;
static final int SERVER_ERROR = 500;
static String describe(int code) {
switch(code) {
case 200: return "OK";
case 201: return "Created";
case 204: return "No Content";
case 400: return "Bad Request";
case 401: return "Unauthorized";
case 404: return "Not Found";
case 500: return "Internal Server Error";
default: return "Unknown";
}
}
}
// Normally: import static HttpCode.*;
// (In single file, we use HttpCode. directly — same concept)
public class StaticImportConstants {
public static void main(String[] args) {
// Without static import:
System.out.println(HttpCode.OK + " - " + HttpCode.describe(HttpCode.OK));
System.out.println(HttpCode.NOT_FOUND + " - " + HttpCode.describe(HttpCode.NOT_FOUND));
// Concept: agar alag file hoti aur import static karte:
// import static HttpCode.*;
// System.out.println(OK + " - " + describe(OK)); ← clean!
// System.out.println(NOT_FOUND + " - " + describe(NOT_FOUND));
System.out.println("\n── All Status Codes ──");
int[] codes = {200, 201, 204, 400, 401, 404, 500};
for (int code : codes) {
System.out.printf(" %d — %s%n", code, HttpCode.describe(code));
}
// Practical: response handling
int responseCode = 404;
if (responseCode == HttpCode.OK) {
System.out.println("Success!");
} else if (responseCode == HttpCode.NOT_FOUND) {
System.out.println("Resource not found!");
} else if (responseCode >= HttpCode.SERVER_ERROR) {
System.out.println("Server error!");
}
}
}
200 - OK 404 - Not Found ── All Status Codes ── 200 — OK 201 — Created 204 — No Content 400 — Bad Request 401 — Unauthorized 404 — Not Found 500 — Internal Server Error Resource not found!
import static java.lang.Math.*;
import static java.lang.System.out;
// JUnit-style assertions (simplified version)
class Assert {
static int passed = 0, failed = 0;
static void assertEquals(Object expected, Object actual, String test) {
if (expected.equals(actual)) {
out.println(" ✔ PASS: " + test); passed++;
} else {
out.println(" ✘ FAIL: " + test + " | Expected=" + expected + " Got=" + actual);
failed++;
}
}
static void assertTrue(boolean cond, String test) {
if (cond) { out.println(" ✔ PASS: " + test); passed++; }
else { out.println(" ✘ FAIL: " + test); failed++; }
}
static void assertFalse(boolean cond, String test) {
assertTrue(!cond, "NOT: " + test);
}
static void summary() {
out.println("\n Results: " + passed + " passed, " + failed + " failed");
}
}
// Class under test
class Calculator {
static int add(int a, int b) { return a + b; }
static int multiply(int a, int b) { return a * b; }
static double squareRoot(double n) { return Math.sqrt(n); }
static boolean isEven(int n) { return n % 2 == 0; }
static int clamp(int v, int lo, int hi) { return Math.max(lo, Math.min(hi, v)); }
}
// Normally: import static Assert.*; and import static Calculator.*;
public class StaticImportTesting {
public static void main(String[] args) {
out.println("═══ Running Calculator Tests ═══\n");
// Addition tests
out.println("── Addition ──");
Assert.assertEquals(5, Calculator.add(2, 3), "add(2,3) = 5");
Assert.assertEquals(0, Calculator.add(-5, 5), "add(-5,5) = 0");
Assert.assertEquals(-8, Calculator.add(-3, -5), "add(-3,-5) = -8");
// Multiply tests
out.println("\n── Multiplication ──");
Assert.assertEquals(6, Calculator.multiply(2, 3), "multiply(2,3) = 6");
Assert.assertEquals(0, Calculator.multiply(0, 99), "multiply(0,99) = 0");
// Square root tests
out.println("\n── Square Root ──");
Assert.assertTrue(abs(Calculator.squareRoot(25) - 5.0) < 0.001, "sqrt(25) ≈ 5.0");
Assert.assertTrue(abs(Calculator.squareRoot(2) - sqrt(2)) < 0.001, "sqrt(2) correct");
// Even tests
out.println("\n── isEven ──");
Assert.assertTrue (Calculator.isEven(4), "4 is even");
Assert.assertFalse(Calculator.isEven(7), "7 is odd");
Assert.assertTrue (Calculator.isEven(0), "0 is even");
// Clamp tests
out.println("\n── Clamp ──");
Assert.assertEquals(100, Calculator.clamp(150, 0, 100), "clamp(150,0,100)=100");
Assert.assertEquals(0, Calculator.clamp(-50, 0, 100), "clamp(-50,0,100)=0");
Assert.assertEquals(50, Calculator.clamp(50, 0, 100), "clamp(50,0,100)=50");
Assert.summary();
}
}
═══ Running Calculator Tests ═══ ── Addition ── ✔ PASS: add(2,3) = 5 ✔ PASS: add(-5,5) = 0 ✔ PASS: add(-3,-5) = -8 ── Multiplication ── ✔ PASS: multiply(2,3) = 6 ✔ PASS: multiply(0,99) = 0 ── Square Root ── ✔ PASS: sqrt(25) ≈ 5.0 ✔ PASS: sqrt(2) correct ── isEven ── ✔ PASS: 4 is even ✔ PASS: NOT: 7 is odd ✔ PASS: 0 is even ── Clamp ── ✔ PASS: clamp(150,0,100)=100 ✔ PASS: clamp(-50,0,100)=0 ✔ PASS: clamp(50,0,100)=50 Results: 13 passed, 0 failed
Topic 6 — Static in Inheritance
Method Hiding vs Overriding — compile-time vs runtime binding
Jab inheritance mein static methods aur variables ka use hota hai, tab ek important concept aata hai: Method Hiding (jo Method Overriding se bilkul alag hai).
Method Overriding (Instance method): Jab child class mein parent ka instance method redefine kiya jaata hai, toh yeh true polymorphism hai. Runtime mein JVM actual object ka type dekhta hai aur child ka method call karta hai — chahe reference parent type ka kyon na ho. Yeh runtime binding hai.
Method Hiding (Static method): Jab child class mein parent ka static method redefine kiya jaata hai, toh yeh override nahi hota — sirf "hide" hota hai. Reference variable ka type (compile-time) decide karta hai kaunsa method call hoga — actual object type nahi. Yeh compile-time binding hai.
Key rule: Static methods are resolved at compile time based on the reference type, NOT the actual object type. Isliye static methods ke saath polymorphism kaam nahi karta.
class Animal {
static String type = "Animal";
// Static method — child mein redefine karo: HIDING (not override)
static void staticSound() {
System.out.println("Animal.staticSound() — reference type decides");
}
// Instance method — child mein redefine karo: TRUE OVERRIDE
void instanceSound() {
System.out.println("Animal.instanceSound() — actual object decides");
}
void describe() {
System.out.println("I am a " + type + " [static variable: compile-time]");
}
}
class Dog extends Animal {
static String type = "Dog"; // variable HIDING
// Method HIDING — NOT override
static void staticSound() {
System.out.println("Dog.staticSound() — woof!");
}
// TRUE Override — runtime polymorphism
@Override
void instanceSound() {
System.out.println("Dog.instanceSound() — WOOF WOOF!");
}
}
public class InheritanceStatic1 {
public static void main(String[] args) {
System.out.println("── ref = new Dog() [Animal reference] ──");
Animal ref = new Dog(); // Dog object, Animal reference
// Static: compile-time → Animal's method (reference type = Animal)
ref.staticSound(); // Animal's!
Animal.staticSound(); // Animal's
Dog.staticSound(); // Dog's
System.out.println();
// Instance: runtime → Dog's method (actual object = Dog)
ref.instanceSound(); // Dog's! (polymorphism)
System.out.println("\n── Variable Hiding ──");
System.out.println("ref.type = " + ref.type); // Animal (compile-time)
System.out.println("Animal.type = " + Animal.type); // Animal
System.out.println("Dog.type = " + Dog.type); // Dog
System.out.println("\n── With actual Dog reference ──");
Dog dog = new Dog();
dog.staticSound(); // Dog's (reference = Dog)
dog.instanceSound(); // Dog's
}
}
── ref = new Dog() [Animal reference] ── Animal.staticSound() — reference type decides Animal.staticSound() — reference type decides Dog.staticSound() — woof! Dog.instanceSound() — WOOF WOOF! ── Variable Hiding ── ref.type = Animal Animal.type = Animal Dog.type = Dog ── With actual Dog reference ── Dog.staticSound() — woof! Dog.instanceSound() — WOOF WOOF!
class Shape {
// Shared static — sabhi shapes count
static int totalShapes = 0;
static String category = "2D Shape";
String color;
Shape(String color) {
this.color = color;
totalShapes++; // har shape — parent + child dono count
}
// Static method — child access kar sakti hai
static void showStats() {
System.out.println("Category: " + category +
" | Total shapes: " + totalShapes);
}
double area() { return 0; } // override karo
}
class Circle extends Shape {
double radius;
static int circleCount = 0;
Circle(String color, double radius) {
super(color);
this.radius = radius;
circleCount++;
}
@Override
double area() { return Math.PI * radius * radius; }
void info() {
System.out.printf("Circle | color=%s | r=%.1f | area=%.2f%n",
color, radius, area());
}
}
class Rectangle extends Shape {
double w, h;
static int rectCount = 0;
Rectangle(String color, double w, double h) {
super(color);
this.w = w; this.h = h;
rectCount++;
}
@Override
double area() { return w * h; }
void info() {
System.out.printf("Rect | color=%s | %gx%g | area=%.2f%n",
color, w, h, area());
}
}
public class InheritanceStatic2 {
public static void main(String[] args) {
Circle c1 = new Circle("Red", 5);
Circle c2 = new Circle("Blue", 3);
Rectangle r1 = new Rectangle("Green", 4, 6);
Rectangle r2 = new Rectangle("Yellow", 10, 2);
Rectangle r3 = new Rectangle("White", 7, 7);
c1.info(); c2.info(); r1.info(); r2.info(); r3.info();
System.out.println();
Shape.showStats(); // parent static method
Circle.showStats(); // same method via child — same result!
System.out.println("Circles : " + Circle.circleCount);
System.out.println("Rectangles: " + Rectangle.rectCount);
System.out.println("category : " + Shape.category);
System.out.println(" = " + Circle.category); // inherited!
}
}
Circle | color=Red | r=5.0 | area=78.54
Circle | color=Blue | r=3.0 | area=28.27
Rect | color=Green | 4.0x6.0 | area=24.00
Rect | color=Yellow | 10x2.0 | area=20.00
Rect | color=White | 7.0x7.0 | area=49.00
Category: 2D Shape | Total shapes: 5
Category: 2D Shape | Total shapes: 5
Circles : 2
Rectangles: 3
category : 2D Shape
= 2D Shape
class GrandParent {
static { System.out.println("1. GrandParent STATIC BLOCK"); }
GrandParent() { System.out.println("4. GrandParent CONSTRUCTOR\n"); }
}
class Parent extends GrandParent {
static { System.out.println("2. Parent STATIC BLOCK"); }
Parent() {
// super() implicit — GrandParent constructor call
System.out.println("5. Parent CONSTRUCTOR");
}
}
class Child extends Parent {
static { System.out.println("3. Child STATIC BLOCK"); }
Child() {
// super() implicit — Parent constructor call
System.out.println("6. Child CONSTRUCTOR");
}
}
public class InheritanceOrder {
public static void main(String[] args) {
System.out.println("=== First Object ===");
Child c1 = new Child();
System.out.println("=== Second Object ===");
Child c2 = new Child(); // static blocks skip honge!
System.out.println("=== Third Object ===");
Child c3 = new Child();
System.out.println("\nOrder Summary:");
System.out.println(" Static: GrandParent → Parent → Child (each once)");
System.out.println(" Constructor: GrandParent → Parent → Child (each time)");
}
}
=== First Object === 1. GrandParent STATIC BLOCK 2. Parent STATIC BLOCK 3. Child STATIC BLOCK 4. GrandParent CONSTRUCTOR 5. Parent CONSTRUCTOR 6. Child CONSTRUCTOR === Second Object === 4. GrandParent CONSTRUCTOR 5. Parent CONSTRUCTOR 6. Child CONSTRUCTOR === Third Object === 4. GrandParent CONSTRUCTOR 5. Parent CONSTRUCTOR 6. Child CONSTRUCTOR Order Summary: Static: GrandParent → Parent → Child (each once) Constructor: GrandParent → Parent → Child (each time)
interface Printable {
// Abstract method — implement karna zaroori
void print();
// Static method — Java 8+ | override nahi hota
static void printHeader(String title) {
System.out.println("═".repeat(40));
System.out.println(" " + title.toUpperCase());
System.out.println("═".repeat(40));
}
// Default method — override kar sakte ho
default void printWithBorder() {
System.out.println("┌" + "─".repeat(38) + "┐");
System.out.print("│ ");
print();
System.out.println("└" + "─".repeat(38) + "┘");
}
}
interface Validatable {
boolean validate();
// Static factory — interface mein
static Validatable of(String value) {
return () -> value != null && !value.trim().isEmpty();
}
static Validatable emailValidator() {
return () -> false; // placeholder
}
}
class Report implements Printable {
String title, content;
Report(String title, String content) {
this.title = title; this.content = content;
}
@Override
public void print() {
System.out.println("Report: " + title + " — " + content);
}
// Note: cannot override Printable.printHeader() — it's static!
}
public class InterfaceStaticMethod {
public static void main(String[] args) {
// Interface static method — only via interface name
Printable.printHeader("Sales Report Q4 2024");
Report r1 = new Report("Revenue", "₹12.5 Lakhs");
Report r2 = new Report("Expenses", "₹8.2 Lakhs");
r1.print();
r1.printWithBorder();
r2.printWithBorder();
Printable.printHeader("Validation Demo");
// Interface static factory
Validatable v1 = Validatable.of("Hello World");
Validatable v2 = Validatable.of(" ");
Validatable v3 = Validatable.of(null);
System.out.println("'Hello World' valid? " + v1.validate()); // true
System.out.println("' ' valid? " + v2.validate()); // false
System.out.println("null valid? " + v3.validate()); // false
// Printable.printHeader cannot be called via Report object!
// r1.printHeader("test"); ← COMPILE ERROR
// Must use: Printable.printHeader("test");
}
}
════════════════════════════════════════ SALES REPORT Q4 2024 ════════════════════════════════════════ Report: Revenue — ₹12.5 Lakhs ┌──────────────────────────────────────┐ │ Report: Revenue — ₹12.5 Lakhs └──────────────────────────────────────┘ ┌──────────────────────────────────────┐ │ Report: Expenses — ₹8.2 Lakhs └──────────────────────────────────────┘ ════════════════════════════════════════ VALIDATION DEMO ════════════════════════════════════════ 'Hello World' valid? true ' ' valid? false null valid? false
Topic 7 — Common Mistakes & Interview Questions
Jo galtiyan sabse zyada hoti hain — aur interview mein jo poochha jaata hai
Static keyword ke saath kuch galtiyan bahut commonly hoti hain — ye compile errors ya unexpected runtime behavior cause karte hain. Teen sabse common mistakes:
- Mistake 1 — Static method mein instance member: Static context mein instance variable ya method directly access karna. Fix: object create karo.
- Mistake 2 — Override vs Hiding confusion: Static method ko @Override se mark karna — compiler warning deta hai. Static methods override nahi hote.
- Mistake 3 — this keyword in static: Static method mein this likhna — compile error. this ka matlab hai "current object" — static context mein koi object nahi hota.
public class StaticMistake1 {
int instanceVar = 10; // instance variable
static int staticVar = 20; // static variable
// ❌ YEH GALAT HAI — compile error aata hai:
/*
static void badMethod() {
System.out.println(instanceVar); // ERROR: non-static field
show(); // ERROR: non-static method
this.instanceVar = 5; // ERROR: 'this' not allowed
}
*/
// ✅ YEH SAHI HAI — static method, static access only
static void correctStaticMethod() {
System.out.println("staticVar = " + staticVar); // ✅ static → static
// Instance chahiye toh: pehle object banao
StaticMistake1 obj = new StaticMistake1();
System.out.println("instanceVar via obj = " + obj.instanceVar); // ✅
obj.show(); // ✅ object se instance method call
}
// ✅ Instance method — both access kar sakta hai
void show() {
System.out.println("show() | instanceVar=" + instanceVar
+ " | staticVar=" + staticVar); // ✅ dono
correctStaticMethod(); // instance → static ✅
}
public static void main(String[] args) {
System.out.println("── From static main ──");
correctStaticMethod();
System.out.println("\n── Via object ──");
StaticMistake1 s = new StaticMistake1();
s.show();
}
}
── From static main ── staticVar = 20 instanceVar via obj = 10 show() | instanceVar=10 | staticVar=20 staticVar = 20 instanceVar via obj = 10 ── Via object ── show() | instanceVar=10 | staticVar=20 staticVar = 20 instanceVar via obj = 10
public class InterviewQ {
// Q1: Static variable sharing across objects
static void q1() {
System.out.println("Q1: Static variable sharing");
class Box {
static int count = 0;
int id;
Box() { count++; id = count; }
}
Box b1 = new Box();
Box b2 = new Box();
Box b3 = new Box();
// What prints?
System.out.println(b1.count); // 3 (not 1!)
System.out.println(b2.count); // 3 (same memory)
System.out.println(b3.id); // 3
}
// Q2: Static method hiding
static void q2() {
System.out.println("\nQ2: Method Hiding");
class Base {
static void greet() { System.out.println("Base"); }
}
class Derived extends Base {
static void greet() { System.out.println("Derived"); }
}
Base ref = new Derived();
ref.greet(); // Base (compile-time! NOT Derived)
Derived.greet(); // Derived
}
// Q3: Static variable vs local variable
static void q3() {
System.out.println("\nQ3: Static vs local scope");
class Counter {
static int s = 0;
void inc() { s++; int local = s; System.out.println("s=" + s + " local=" + local); }
}
Counter c1 = new Counter();
Counter c2 = new Counter();
c1.inc(); c2.inc(); c1.inc();
// s is shared: 1, 2, 3
// local is new each call: always equals s at that moment
}
// Q4: null object calling static member
static void q4() {
System.out.println("\nQ4: Null object static access");
class Weird {
static int x = 42;
static void hi() { System.out.println("hi! x=" + x); }
}
Weird w = null;
System.out.println(w.x); // 42 — no NullPointerException! static!
w.hi(); // Works! static method, no object needed
}
public static void main(String[] args) {
q1(); q2(); q3(); q4();
System.out.println("\n── Key Takeaways ──");
System.out.println("1. null object se static access — NullPointerException NAHI aata");
System.out.println("2. Static method ref = new Child() → Parent ka method chale");
System.out.println("3. Static variable sab share karte hain — b1.count = b2.count");
System.out.println("4. Local variable = method scope mein, static nahi ho sakta");
}
}
Q1: Static variable sharing 3 3 3 Q2: Method Hiding Base Derived Q3: Static vs local scope s=1 local=1 s=2 local=2 s=3 local=3 Q4: Null object static access 42 hi! x=42 ── Key Takeaways ── 1. null object se static access — NullPointerException NAHI aata 2. Static method ref = new Child() → Parent ka method chale 3. Static variable sab share karte hain — b1.count = b2.count 4. Local variable = method scope mein, static nahi ho sakta
public class InterviewQBank {
static int x = 5;
// Q: Can static method be synchronized? YES!
static synchronized void syncMethod() {
System.out.println("✅ Q1: static synchronized — YES (class-level lock)");
}
// Q: Can we have static method in abstract class? YES!
static abstract class AbstractBase {
static void staticInAbstract() {
System.out.println("✅ Q2: static in abstract class — YES");
}
abstract void abstractMethod(); // child implement karega
}
// Q: Can interface have static method? YES (Java 8+)
interface MyInterface {
static void interfaceStatic() {
System.out.println("✅ Q3: static in interface — YES (Java 8+)");
}
}
// Q: Can we call static method from constructor? YES
static void helperFromConstructor() {
System.out.println("✅ Q4: static from constructor — YES | x=" + x);
}
InterviewQBank() {
helperFromConstructor();
x++;
}
// Q: Can static variable be local (inside method)? NO!
static void noLocalStatic() {
// static int localStatic = 5; ← COMPILE ERROR
int local = 5; // local variable — static nahi ho sakta
System.out.println("❌ Q5: local static var — NO (compile error) | local=" + local);
}
// Q: Can static method be overridden? NO — only hidden
static void cannotOverride() {
System.out.println("❌ Q6: static method override — NO (only method hiding)");
}
// Q: Can we use this in static method? NO
static void noThis() {
// System.out.println(this.x); ← COMPILE ERROR
System.out.println("❌ Q7: 'this' in static — NO (compile error)");
}
// Q: What is class loading order?
static { System.out.println("Q8: static block runs at class load — BEFORE main()"); }
public static void main(String[] args) {
System.out.println("\n── Interview Q&A ──\n");
syncMethod();
AbstractBase.staticInAbstract();
MyInterface.interfaceStatic();
System.out.println("Q4: Calling constructor:");
InterviewQBank obj = new InterviewQBank();
noLocalStatic();
cannotOverride();
noThis();
System.out.println("\nFinal x = " + x + " (incremented in constructor)");
}
}
Q8: static block runs at class load — BEFORE main() ── Interview Q&A ── ✅ Q1: static synchronized — YES (class-level lock) ✅ Q2: static in abstract class — YES ✅ Q3: static in interface — YES (Java 8+) Q4: Calling constructor: ✅ Q4: static from constructor — YES | x=5 ❌ Q5: local static var — NO (compile error) | local=5 ❌ Q6: static method override — NO (only method hiding) ❌ Q7: 'this' in static — NO (compile error) Final x = 6 (incremented in constructor)
// UNSAFE counter — race condition!
class UnsafeCounter {
static int count = 0;
static void increment() { count++; } // not thread-safe!
}
// SAFE counter — synchronized static method
class SafeCounter {
private static int count = 0;
static synchronized void increment() {
count++; // class-level lock — only one thread at a time
}
static synchronized int getCount() { return count; }
static synchronized void reset() { count = 0; }
}
public class ThreadSafetyDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("── Safe Counter Demo ──");
// Simulate 5 threads each incrementing 100 times
Thread[] threads = new Thread[5];
for (int i = 0; i < 5; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < 100; j++) {
SafeCounter.increment();
}
}, "Thread-" + (i+1));
}
for (Thread t : threads) t.start();
for (Thread t : threads) t.join(); // wait for all threads
System.out.println("Expected : 500");
System.out.println("Got : " + SafeCounter.getCount());
System.out.println("Correct? : " + (SafeCounter.getCount() == 500));
System.out.println("\n── Key Points ──");
System.out.println("• static + synchronized = class-level lock");
System.out.println("• instance + synchronized = object-level lock");
System.out.println("• Shared static state in multi-threaded apps = potential race condition");
System.out.println("• Always synchronize when multiple threads share static state");
}
}
── Safe Counter Demo ── Expected : 500 Got : 500 Correct? : true ── Key Points ── • static + synchronized = class-level lock • instance + synchronized = object-level lock • Shared static state in multi-threaded apps = potential race condition • Always synchronize when multiple threads share static state
Topic 8 — Real Backend Patterns with Static
Production-grade code mein static kaise use hota hai
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
class AppLogger {
private static AppLogger instance = null;
private static int logCount = 0;
private static final DateTimeFormatter FMT =
DateTimeFormatter.ofPattern("HH:mm:ss");
private String appName;
private AppLogger(String name) {
this.appName = name;
System.out.println("[LOGGER] Logger initialized for: " + appName);
}
public static AppLogger getInstance(String name) {
if (instance == null) instance = new AppLogger(name);
return instance;
}
private String ts() { return LocalDateTime.now().format(FMT); }
void info (String msg) { log("INFO ", msg); }
void warn (String msg) { log("WARN ", msg); }
void error(String msg) { log("ERROR", msg); }
void debug(String msg) { log("DEBUG", msg); }
private void log(String level, String msg) {
logCount++;
System.out.printf("[%s] [%s] [%s] #%d — %s%n",
ts(), level, appName, logCount, msg);
}
static int getLogCount() { return logCount; }
}
public class BackendLogger {
public static void main(String[] args) {
AppLogger log = AppLogger.getInstance("ECommerceApp");
AppLogger log2 = AppLogger.getInstance("ECommerceApp"); // same!
System.out.println("Same instance: " + (log == log2));
log.info("Server started on port 8080");
log.info("Database connected");
log.debug("Request: GET /api/products");
log.warn("Cache miss ratio above 20%");
log.info("Response: 200 OK (45ms)");
log.error("Payment gateway timeout!");
log2.warn("Retry attempt 1/3");
log2.info("Retry success");
System.out.println("\nTotal log entries: " + AppLogger.getLogCount());
}
}
[LOGGER] Logger initialized for: ECommerceApp Same instance: true [14:32:01] [INFO ] [ECommerceApp] #1 — Server started on port 8080 [14:32:01] [INFO ] [ECommerceApp] #2 — Database connected [14:32:01] [DEBUG] [ECommerceApp] #3 — Request: GET /api/products [14:32:01] [WARN ] [ECommerceApp] #4 — Cache miss ratio above 20% [14:32:01] [INFO ] [ECommerceApp] #5 — Response: 200 OK (45ms) [14:32:01] [ERROR] [ECommerceApp] #6 — Payment gateway timeout! [14:32:01] [WARN ] [ECommerceApp] #7 — Retry attempt 1/3 [14:32:01] [INFO ] [ECommerceApp] #8 — Retry success Total log entries: 8
import java.util.*;
class MemoCache {
// Static cache — program lifetime tak persist karta hai
private static final Map<Integer, Long> fibCache = new HashMap<>();
private static final Map<Integer, Long> factCache = new HashMap<>();
private static int cacheHits = 0;
private static int cacheMiss = 0;
static long fib(int n) {
if (n <= 1) return n;
if (fibCache.containsKey(n)) { cacheHits++; return fibCache.get(n); }
cacheMiss++;
long result = fib(n-1) + fib(n-2);
fibCache.put(n, result);
return result;
}
static long fact(int n) {
if (n <= 1) return 1;
if (factCache.containsKey(n)) { cacheHits++; return factCache.get(n); }
cacheMiss++;
long result = n * fact(n-1);
factCache.put(n, result);
return result;
}
static void printStats() {
System.out.println("Cache Hits : " + cacheHits);
System.out.println("Cache Misses : " + cacheMiss);
System.out.printf ("Hit Rate : %.1f%%%n",
(double)cacheHits / (cacheHits+cacheMiss) * 100);
System.out.println("Fib Cache sz : " + fibCache.size());
System.out.println("Fact Cache sz: " + factCache.size());
}
public static void main(String[] args) {
System.out.println("── First Calls (cache cold) ──");
long t1 = System.nanoTime();
System.out.println("fib(40) = " + fib(40));
System.out.println("fib(30) = " + fib(30));
System.out.println("fact(15) = " + fact(15));
long t2 = System.nanoTime();
System.out.println("Time: " + (t2-t1)/1000 + " μs");
System.out.println("\n── Second Calls (cache warm) ──");
long t3 = System.nanoTime();
System.out.println("fib(40) = " + fib(40)); // from cache!
System.out.println("fib(35) = " + fib(35)); // partially cached
System.out.println("fact(15) = " + fact(15)); // from cache!
long t4 = System.nanoTime();
System.out.println("Time: " + (t4-t3)/1000 + " μs ← MUCH faster!");
System.out.println("\n── Cache Statistics ──");
printStats();
}
}
── First Calls (cache cold) ── fib(40) = 102334155 fib(30) = 832040 fact(15) = 1307674368000 Time: 842 μs ── Second Calls (cache warm) ── fib(40) = 102334155 fib(35) = 9227465 fact(15) = 1307674368000 Time: 12 μs ← MUCH faster! ── Cache Statistics ── Cache Hits : 43 Cache Misses : 54 Hit Rate : 44.3% Fib Cache sz : 40 Fact Cache sz: 14
import java.util.*;
interface Handler {
String handle(String method, String body);
}
class Router {
// Static route registry — program-wide
private static final Map<String, Handler> routes = new LinkedHashMap<>();
private static final List<String> requestLog = new ArrayList<>();
private static int requestCount = 0;
// Register route — static method
static void route(String path, Handler handler) {
routes.put(path, handler);
System.out.println("[ROUTER] ✔ Registered: " + path);
}
// Dispatch request — static method
static String dispatch(String method, String path, String body) {
requestCount++;
String logEntry = "#" + requestCount + " " + method + " " + path;
requestLog.add(logEntry);
Handler h = routes.get(path);
if (h == null) return "404 Not Found: " + path;
return h.handle(method, body);
}
static void printLog() {
System.out.println("\n── Request Log ──");
requestLog.forEach(e -> System.out.println(" " + e));
System.out.println("Total requests: " + requestCount);
}
}
public class StaticRouterDemo {
public static void main(String[] args) {
// Route registration (like @GetMapping, @PostMapping)
Router.route("/api/users", (method, body) -> {
if ("GET".equals(method)) return "200 [{id:1,name:Rahul}, {id:2,name:Priya}]";
if ("POST".equals(method)) return "201 Created user: " + body;
return "405 Method Not Allowed";
});
Router.route("/api/products", (method, body) -> {
if ("GET".equals(method)) return "200 [{id:101,name:Laptop,price:75000}]";
return "405 Method Not Allowed";
});
Router.route("/api/health", (m, b) -> "200 {status:UP, uptime:99.9%}");
System.out.println("\n── Processing Requests ──");
String[] responses = {
Router.dispatch("GET", "/api/users", null),
Router.dispatch("POST", "/api/users", "{name:Amit,email:amit@g.com}"),
Router.dispatch("GET", "/api/products", null),
Router.dispatch("DELETE", "/api/products", null),
Router.dispatch("GET", "/api/health", null),
Router.dispatch("GET", "/api/unknown", null)
};
for (String resp : responses) System.out.println(" → " + resp);
Router.printLog();
}
}
[ROUTER] ✔ Registered: /api/users
[ROUTER] ✔ Registered: /api/products
[ROUTER] ✔ Registered: /api/health
── Processing Requests ──
→ 200 [{id:1,name:Rahul}, {id:2,name:Priya}]
→ 201 Created user: {name:Amit,email:amit@g.com}
→ 200 [{id:101,name:Laptop,price:75000}]
→ 405 Method Not Allowed
→ 200 {status:UP, uptime:99.9%}
→ 404 Not Found: /api/unknown
── Request Log ──
#1 GET /api/users
#2 POST /api/users
#3 GET /api/products
#4 DELETE /api/products
#5 GET /api/health
#6 GET /api/unknown
Total requests: 6
class HttpStatus {
// 2xx Success
static final int OK = 200;
static final int CREATED = 201;
static final int ACCEPTED = 202;
static final int NO_CONTENT = 204;
// 3xx Redirect
static final int MOVED_PERMANENTLY = 301;
static final int NOT_MODIFIED = 304;
// 4xx Client Error
static final int BAD_REQUEST = 400;
static final int UNAUTHORIZED = 401;
static final int FORBIDDEN = 403;
static final int NOT_FOUND = 404;
static final int CONFLICT = 409;
static final int TOO_MANY_REQ = 429;
// 5xx Server Error
static final int SERVER_ERROR = 500;
static final int BAD_GATEWAY = 502;
static final int UNAVAILABLE = 503;
static String message(int code) {
switch(code) {
case 200: return "OK"; case 201: return "Created";
case 202: return "Accepted"; case 204: return "No Content";
case 301: return "Moved Permanently"; case 304: return "Not Modified";
case 400: return "Bad Request"; case 401: return "Unauthorized";
case 403: return "Forbidden"; case 404: return "Not Found";
case 409: return "Conflict"; case 429: return "Too Many Requests";
case 500: return "Internal Server Error";
case 502: return "Bad Gateway"; case 503: return "Service Unavailable";
default: return "Unknown";
}
}
static boolean isSuccess(int c) { return c >= 200 && c < 300; }
static boolean isRedirect(int c) { return c >= 300 && c < 400; }
static boolean isClientError(int c) { return c >= 400 && c < 500; }
static boolean isServerError(int c) { return c >= 500; }
static String category(int c) {
if (isSuccess(c)) return "✅ SUCCESS";
if (isRedirect(c)) return "↪ REDIRECT";
if (isClientError(c)) return "❌ CLIENT ERR";
if (isServerError(c)) return "💥 SERVER ERR";
return "UNKNOWN";
}
public static void main(String[] args) {
int[] codes = {200,201,301,400,401,403,404,409,429,500,503};
System.out.printf("%-5s %-25s %-14s%n", "Code", "Message", "Category");
System.out.println("─".repeat(48));
for (int c : codes)
System.out.printf("%-5d %-25s %-14s%n", c, message(c), category(c));
System.out.println("\n── Usage in code ──");
int res = 404;
if (HttpStatus.isClientError(res)) {
System.out.println("Client made a bad request: " + HttpStatus.message(res));
}
}
}
Code Message Category ──────────────────────────────────────────────── 200 OK ✅ SUCCESS 201 Created ✅ SUCCESS 301 Moved Permanently ↪ REDIRECT 400 Bad Request ❌ CLIENT ERR 401 Unauthorized ❌ CLIENT ERR 403 Forbidden ❌ CLIENT ERR 404 Not Found ❌ CLIENT ERR 409 Conflict ❌ CLIENT ERR 429 Too Many Requests ❌ CLIENT ERR 500 Internal Server Error 💥 SERVER ERR 503 Service Unavailable 💥 SERVER ERR ── Usage in code ── Client made a bad request: Not Found
⭐ Complete Quick Reference & Summary
static int count;Class-level, single copy, all share. Method Area mein store. Default values milti hain.
static void help() {}Object ke bina call. this/instance nahi. main() isi liye static hai.
static { ... }Class load pe sirf once. main() se pehle. Config/driver loading ke liye.
static class Inner {}Outer object nahi chahiye. Builder, Node patterns mein use hoti hai.
import static Math.*;Class name likhne ki zaroorat nahi. Math ops, JUnit testing mein useful.
🎯 Exam & Interview — Must Remember Points
- static = Class ka hai, Object ka nahi — Method Area mein store hota hai
- Static variable — sirf ek copy, sabhi objects share karte hain, class se access karo
- Static method — object banaye bina call karo:
ClassName.method() - Static block — class load pe sirf ek baar, main() se bhi pehle
- Static nested class — outer object ki zaroorat nahi, outer.static members only access
- Static method — override nahi hota, sirf hide hota hai (Method Hiding)
- main() static kyun? — JVM object banaye bina call kare isliye
- Execution order: Parent static → Child static → Parent ctor → Child ctor
- static final = constant — convention: ALL_CAPS naam rakhte hain
- Interface mein static method — Java 8+ se allowed, override nahi hota
- null object se static access — NullPointerException nahi aata!
- Static variable = global shared state — multi-threading mein careful!
⚠️ Common Mistakes — Wrong vs Right
| Situation | ❌ Wrong | ✅ Right |
|---|---|---|
| Instance in static | static void m() { instanceVar++; } |
Object create karo, fir access karo |
| this in static | static void m() { this.x = 5; } |
this static mein nahi — remove karo |
| Static via object | obj.staticMethod() ← misleading |
ClassName.staticMethod() |
| Override static | @Override static void greet() |
Static sirf hide hota hai, @Override nahi |
| Local static var | void m() { static int x = 5; } |
Local variables static nahi ho sakte |
| Static block dobara | 10 objects → static block 10 baar chala | Static block sirf EK baar — class load pe |
| Nested class creation | new Outer().new Static.Nested() |
new Outer.StaticNested() |
| Thread safety | Multiple threads ek static var modify karein | static synchronized method use karo |
🏆 Golden Rule
"static = Class ka member, Object ka nahi — yeh ek cheez yaad karo, baaki sab samajh aayega"
☕ Java Static Keyword & Class — Complete Deep Guide | Keep Coding! 🚀