After 14 years in Java backend, I realized something uncomfortable. I had never consciously used WeakReference, SoftReference, or PhantomReference in production. And yet — I was benefiting from them every single day without knowing it. Let me explain. 👇 ───────────────────────── A few years back, our service started leaking memory. Slowly. Silently. The heap grew. GC ran more. Latency spiked. Classic signs. After hours of heap dumps and profiling, we found it. A listener registry. Objects were no longer in use. But GC couldn't clean them. Root cause? Strong references in a static listener list. Fix? Switched to WeakReference. The leak disappeared. That day, I stopped treating reference types as "theoretical JVM knowledge." ───────────────────────── Here's what I wish I had understood earlier: 🔴 Strong Reference Object obj = new Object(); GC never touches it. As long as this reference exists, the object lives. → The silent cause of most memory leaks in long-running services. 🟡 Soft Reference SoftReference<byte[]> cache = new SoftReference<>(data); GC evicts only under memory pressure. → Historically used for caches. Modern systems now prefer explicit eviction strategies (e.g., Caffeine, Guava Cache) — more predictable under load. 🟠 Weak Reference WeakReference<User> ref = new WeakReference<>(user); GC collects at the next cycle if no strong reference exists. → Ideal for listener registries, observer patterns, and WeakHashMap. → This is what fixed our leak. 🟤 Phantom Reference PhantomReference<Object> phantom = new PhantomReference<>(obj, queue); The object is already gone when you get notified. → Used for native/off-heap resource cleanup. In modern Java (9+), the Cleaner API is the cleaner alternative. ───────────────────────── The mental model that stuck with me: Strong → "I own this. Never release." Soft → "Keep if memory allows." Weak → "Release when no one else cares." Phantom → "Notify me when it's truly dead." ───────────────────────── If you've never used these explicitly, you're not alone. But knowing when to reach for them? That's where senior engineering starts. Have you ever debugged a memory leak like this? What was the root cause? Drop it below 👇 — I'd genuinely love to compare notes. #Java #JVM #GarbageCollection #BackendEngineering #JavaDeveloper #JavaPerformance #SoftwareEngineering #Performance
WeakReferences in Java: A Senior Engineer's Secret to Memory Leaks
More Relevant Posts
-
🚀 Backend Systems | Post - 3 | How to create Threads in JAVA In the last posts, we understood Multithreading, and the difference between Concurrency and Parallelism , now lets learns how do we actually create threads in Java. 1. Extending the Thread Class You can create a thread by having a subclass which extends the Thread class and overriding the run() method. class MyThread extends Thread { @Override public void run() { System.out.println("Hello World"); } } MyThread t1 = new MyThread(); t1.start(); 2. Implementing Runnable Interface (this is usually recommended) This is the most commonly used approach in real-world systems having a class implements the runnable interface and overriding the run method. what is Runnable interface ? It is functional interface which has only one abstract function run. class MyRunnable implements Runnable { @Override public void run() { System.out.println("Hello World"); } } Thread t1 = new Thread(new MyRunnable()); t1.start(); 💡 Why is this better? --> as in java multilevel inheritance isn't possible with classes but possible with interface , since runnable is a interface because of that it allows for multilevel inheritance , this approach is usually better in backend systems. 3. Using Lambda (Modern Java🔥) In modern java we use lambda as a shortcut way to implement a functional interface , since Runnable is also a functional interface , we use this way when this line of code will only be used only by this thread. Thread t1 = new Thread(() -> { System.out.println("Hello World"); }); t1.start(); ⚠️ Common Mistake (VERY IMPORTANT) Most beginners think this will create a thread: Calling run() directly -->This will NOT create a new thread --> It just runs like a normal function call. --> the correct way is to always use start() to create a new thread. 🚀 Key Takeaways --> Runnable is better than Thread for better design. --> Lambda is a clean way to implement Runnable. --> start() creates a thread, run() does not. #Multithreading #Java #OperatingSystem #BackenedSystems
To view or add a comment, sign in
-
Don’t let the lack of flashy headlines fool you — Java 26 is one of the most important “quiet” releases for the future of the JVM. Released on March 17, 2026, Java 26 is less about hype and more about strengthening the platform’s foundations: integrity, performance, and long-term architectural direction. Here’s why it matters: **1. Making “final” actually trustworthy (JEP 500)** Java is tightening a decades-old loophole. In JDK 26, mutating `final` fields via deep reflection now triggers runtime warnings by default. This matters because the more the JVM can trust immutability, the more safely it can optimize code. **2. HTTP/3 arrives in the standard HttpClient (JEP 517)** Java’s modern `HttpClient` now supports HTTP/3. That doesn’t mean HTTP/3 becomes the default automatically — it’s opt-in — but it does mean modern networking is now part of the standard platform, not an external extra. **3. Real performance work where it counts (JEP 522 & 516)** * **G1 GC** gets a meaningful throughput boost by reducing synchronization overhead. OpenJDK reports observed gains of **5–15%** for workloads that heavily modify object references. * **Ahead-of-Time Object Caching** now works with **any GC**, including ZGC, helping improve startup and warmup behavior. **4. The language keeps moving toward uniformity (JEP 530 & 526)** * **Primitive types in patterns / `instanceof` / `switch`** continue in preview, pushing Java toward a more consistent language model. * **Lazy Constants**, also still in preview, offer a compelling model for deferred immutable initialization. **5. Legacy cleanup is now complete (JEP 504)** The Applet API is officially gone. Java 26 continues the platform’s long-term cleanup by removing technology that has been obsolete for years. **The bottom line** Java 26 is a bridge release in the best sense: not a loud one, but a deeply strategic one. It strengthens the JVM’s trust model, modernizes the network stack, improves real-world performance, and keeps pushing the language forward. Are you staying on Java 25 LTS for now, or already experimenting with Java 26? #Java26 #JDK26 #ModernJava #JVM #BackendEngineering #Java
To view or add a comment, sign in
-
-
🚀 Java’s volatile Keyword — The Most Misunderstood Concept (Explained Like Real Life) If you’ve worked with multithreading, you’ve probably seen volatile… and thought: 👉 “It makes things thread-safe, right?” ❌ Not exactly. Let’s break it down in a way that actually sticks 👇 🏠 Real-Life Example: WhatsApp Status Problem Imagine: You update your WhatsApp status. But your friend still sees the old status for a while 😅 Why? 👉 Because their app is showing a cached version, not the latest one 🧠 Same Problem Happens in Java Threads Each thread has its own working memory (CPU cache) So if one thread updates a variable: 👉 Other threads may still see the old value 💥 This is called a visibility problem ⚡ What volatile Actually Does When you mark a variable as volatile: volatile boolean isRunning = true; 👉 You’re telling JVM: “Always read/write this variable directly from main memory” 📌 So What Problems Does It Solve? ✔️ Guarantees visibility ✔️ Prevents threads from using stale values ⚠️ But Here’s the Catch (Important for Interviews) 👉 volatile does NOT guarantee: ❌ Atomicity ❌ Thread safety for complex operations 💥 Classic Mistake Example java volatile int count = 0; count++; // Not safe ❌ Why? 👉 count++ is NOT a single operation It’s actually: 1️⃣ Read 2️⃣ Increment 3️⃣ Write Two threads can still mess this up 🧠 What Else Does volatile Do? (Deep Concept) 👉 It prevents instruction reordering Sounds complex? Let’s simplify 👇 🍳 Real-Life Analogy: Cooking Order Imagine making tea: 1️⃣ Boil water 2️⃣ Add tea leaves Now imagine someone reorders it: 👉 Add tea leaves first, then boil 😅 Program still runs… but result is wrong ⚙️ Same Happens in CPU Optimizations To improve performance, JVM/CPU may reorder instructions 👉 volatile prevents this for that variable 🔥 Most Important Use Case: Stop Thread Pattern volatile boolean running = true; while(running) { // do work } Another thread can safely do: java running = false; 👉 Without volatile, loop might NEVER stop 🧠 Interview Questions (Answered Simply) 👉 What problem does volatile solve? → Visibility + Ordering 👉 Is volatile thread-safe? → ❌ No (only for simple reads/writes) 👉 Difference between volatile & synchronized? | volatile | synchronized | |----------|-------------| | Visibility only | Visibility + Atomicity | | No locking | Uses locking | | Faster | Slower | 🎯 When Should You Use volatile? ✔️ Status flags (true/false) ✔️ Configuration updates ✔️ One writer, multiple readers ❌ Avoid for: - Counters - Banking logic - Complex shared state #Java #Multithreading #Volatile #Concurrency #BackendDevelopment #InterviewPrep #SoftwareEngineer
To view or add a comment, sign in
-
🚀 Java Wrapper Classes: Hidden Behaviors That Trip Up Even Senior Developers Most developers know wrapper classes. Very few understand what happens under the hood — and that’s exactly where top companies separate candidates. Here’s a deep dive into the concepts that actually matter 1. Integer Caching Integer a = 4010; Integer b = 4010; System.out.println(a == b); // false Integer c = 127; Integer d = 127; System.out.println(c == d); // true Q.Why? Java caches Integer values in the range -128 to 127. Inside range → same object (cached) Outside range → new object (heap) 💡 Pro Insight: You can even extend this range using: -XX:AutoBoxCacheMax=<size> 2. == vs .equals() — Silent Bug Generator System.out.println(a == b); // false → reference comparison System.out.println(a.equals(b)); // true → value comparison Using == with wrapper objects is one of the most common production bugs. Rule: == → checks memory reference .equals() → checks actual value 3. hashCode() vs identityHashCode() System.out.println(a.hashCode()); System.out.println(System.identityHashCode(a)); Two objects can have: Same value → same hashCode() Different memory → different identityHashCode() 4. Silent Overflow in Primitive Conversion Integer a = 4010; byte k = a.byteValue(); // -86 What actually happens: byte range = -128 to 127 4010 % 256 = 170 170 interpreted as signed → -86 No error. No warning. This is how real-world bugs sneak into systems. 5. Powerful Utility Methods (Underrated) Integer.toBinaryString(4010); Integer.toHexString(4010); Integer.bitCount(4010); Integer.numberOfLeadingZeros(4010); Useful in: Bit manipulation Competitive programming Low-level optimization 6. Character & Boolean — Also Cached Boolean b1 = true; Boolean b2 = true; System.out.println(b1 == b2); // true Boolean → fully cached Character → cached in ASCII range 7. Character Utilities = Clean Code Character.isLetter('a'); Character.isDigit('3'); Character.isWhitespace('\t'); Character.toUpperCase('a'); The Big Picture Wrapper classes are NOT just primitives with methods. They reveal how Java handles: Memory optimization Object identity Autoboxing behavior Performance trade-offs A big thanks to my mentors Syed Zabi Ulla, peers, and the amazing developer community Oracle for continuously pushing me to go beyond basics and truly understand concepts at a deeper level. #Java #JVM #CoreJava #CodingInterview #FAANG #SoftwareEngineering #BackendDevelopment #ProgrammingTips
To view or add a comment, sign in
-
-
Java 26 just dropped and if you’re still thinking Java is “just backend”, you’re already behind. This release is quietly aligning the JVM for an AI-first world. Here’s what actually matters: 1. AOT Object Caching + ZGC support (JEP 516) Train once. Cache object graphs. Ship faster startups with any GC. For LLM services and Agentic AI systems, cold start latency is no longer your bottleneck. This is real infra leverage, not hype. 2. HTTP/3 built into the standard library (JEP 517) QUIC means better resilience, less head-of-line blocking. If you’re calling Gen AI APIs or streaming responses, this directly improves reliability without extra libraries. 3. Structured Concurrency keeps getting stronger (JEP 525) Multi-agent orchestration is messy. This gives you controlled lifecycles, failure propagation, and clean cancellation. Exactly what Agentic AI workflows need. 4. Lazy Constants (JEP 526) Heavy configs, model clients, embeddings don’t need eager init. Defer cost, keep performance. Small feature, big impact at scale. 5. Primitive patterns in switch (JEP 530) Parsing LLM JSON outputs is still painful. Safer numeric handling means fewer silent bugs. Less defensive code, more intent. 6. G1 GC throughput improvements (JEP 522) Less synchronization, faster write barriers. Up to double-digit throughput gains in object-heavy workloads. If you’re doing token processing or embeddings, this compounds over time. 7. Finally Final is Final (JEP 500) Final fields are getting real integrity. Reflection hacks are being restricted. Better correctness. Better JVM optimizations. If your framework depends on mutating final fields, you have technical debt to fix. 8. PEM API improvements (JEP 524) Handling keys, certs, encryption gets simpler. This matters when you’re integrating secure AI pipelines and external model providers. 9. Applet API is finally gone (JEP 504) If you’re still holding onto that era, that’s not nostalgia, that’s stagnation. Here’s the uncomfortable truth: Most teams are stuck on Java 17 not because it’s “stable” But because they’re avoiding change Meanwhile the JVM is evolving into a serious runtime for Gen AI, LLM infra, and Agentic systems Faster startup, Better concurrency, Stronger guarantees, Cleaner APIs You can either treat Java as legacy OR start using it like a modern backend platform JDK 26 Notes: http://bit.ly/4sh1g1S What are you actually excited to use from JDK 26? #Java #JDK26 #OpenJDK #BackendEngineering #GenerativeAI #AgenticAI #LLM #JVM #SoftwareEngineering
To view or add a comment, sign in
-
-
Let’s talk about Optional in Java. ☕ When should you use it, and when should you avoid it? Recently, I saw a post suggesting using Optional as a method parameter to simulate Kotlin's Elvis operator (?:). This is actually an anti-pattern! Let's review when to use it and when to avoid it, inspired by Stuart Marks’s famous talk on the topic. What’s the actual problem with null in Java? It’s semantic ambiguity: is it an error, an uninitialized variable, or a legitimate absence of a value? This forces us into defensive coding (if (obj != null)) to avoid the dreaded NPEs. Java introduced Optional<T> to declare a clear API contract: "This value might not be present; it's your responsibility to decide how to handle its absence." ✅ WHERE TO USE OPTIONAL: 👉 Method Return Types: This is its primary design purpose. It clearly communicates that a result might be empty: Optional<SaleEntity> findSaleById(Long id) 👉 Safe Transformations: Extract nested data without breaking your flow with intermediate null checks: var city = Optional.ofNullable(client) .map(Client::getAddress) .map(Address::getCity) .orElse("Unknown"); 👉 Stream Pipelines: Using flatMap(Optional::stream) elegantly filters a stream, leaving only the present values without cluttering your code. ❌ WHERE NOT TO USE OPTIONAL (ANTI-PATTERNS): 👉 Method Parameters: Never do this. It complicates the signature, creates unnecessary object allocation, and doesn't even prevent someone from passing a null instead of an Optional! Use internal validations (Objects.requireNonNull). 👉 Calling .get() without checking: Never call Optional.get() unless you can mathematically prove it contains a value. Prefer alternatives like .orElse(), .orElseGet(), or .ifPresent(). 👉 Returning Null for an Optional: If your method returns an Optional, returning a literal null defeats the entire purpose and will cause unexpected NPEs downstream. Always return Optional.empty(). 👉 Class Fields (Attributes): Optional is not Serializable. Use a documented null or the "Null Object Pattern". 👉 Collections: Never return Optional<List<T>>. Just return an empty list (Collections.emptyList()). It's semantically correct and saves memory. Optional doesn't eradicate null, but it helps us design more honest APIs. Let's use it responsibly. 🛠️ To dive deeper, I've attached a PDF summary of the core rules for Optionals. 📄👇 What other anti-patterns have you seen when using Optionals? Let me know below! (PS: I'll leave the link to Stuart Marks's full video breakdown in the first comment). #Java #SoftwareEngineering #CleanCode #Backend #JavaDeveloper #Optional
To view or add a comment, sign in
-
💡 Most Java devs use .equals() for Strings without knowing why == breaks. Here's the full picture — every concept connected. 🔷 String is an Object — and Immutable String is not a primitive. It's an object. And it's immutable — once created, its value never changes. String s = "Java"; s = s + " Dev"; → "Java" is NOT touched → "Java Dev" is a brand new object → 's' just shifts its reference to the new one Immutability is why JVM can safely share and reuse String objects. 🔷 Where Strings Live — The String Pool All objects go into Heap. But String literals go into a special zone inside Heap called the String Pool. The Pool stores only unique values — no duplicates. String s1 = "Java"; → JVM creates "Java" in pool String s2 = "Java"; → already exists → s2 gets same reference s1 == s2 → true ✅ (same object, same address) But new String("Java") bypasses the pool — creates a fresh Heap object. s1 == s3 → false ❌ (different references) s1.equals(s3) → true ✅ (same content) 🔷 What == Actually Does == compares references — the memory address — not values. → Same object → true → Different object, same value → false This is the root cause of every String comparison bug in Java. 🔷 Compile-time vs Runtime — a Trap Most Miss String s2 = "Ja" + "va"; → folded at compile time → pool → s1 == s2 ✅ String part = "Ja"; String s3 = part + "va"; → built at runtime → new Heap object → s1 == s3 ❌ Same output. Completely different memory behavior. 🔷 Default equals() — What Most Don't Know Every class inherits equals() from java.lang.Object. The default implementation? public boolean equals(Object obj) { return (this == obj); } Just == in disguise. Reference comparison — not value. String overrides this — compares characters directly. That's why s1.equals(s3) → true ✅ always. 🔷 intern() — Taking Back Control String s4 = new String("Java").intern(); → intern() fetches the pool reference → s4 now points to the same object as s1 s1 == s4 → true ✅ Useful in performance-sensitive code. In everyday apps — just use .equals(). Immutability → JVM safely shares Strings String Pool → unique literals, no duplicates == → reference comparison, not value Default equals() → also reference comparison String.equals() → overrides it, compares content intern() → pulls Heap object back to pool Not six facts. One connected idea. 💬 Which part clicked for you? What Java concept should I cover next? #Java #JVM #StringPool #BackendDevelopment #SoftwareEngineering #JavaDeveloper #LearnJava
To view or add a comment, sign in
-
-
🚀🎊Day 89 of 90 – Java Backend Development ✨🎆 Choosing between an abstract class and an interface is less about what the code does and more about what the code is. Both are tools for abstraction, but they serve different architectural purposes. 👉1. When to use an abstract class: Think of an abstract class as a blueprint for a specific family. You use it when you want to share code among several closely related classes. i) The "Is-A" Relationship: Use an abstract class when your objects share a common identity. For example, a GoldenRetriever is a Dog. ii) Shared State or Base Logic: If you want to provide default behavior or keep track of common variables (like age or color), an abstract class is the way to go. iii) Access Control: Use them if you need to use protected or private methods to hide internal logic from the outside world. 👉2. When to use an interface: Think of an interface as a contract or a peripheral. It defines a capability that a class must have, regardless of what kind of class it is. i) The "Can-Do" Relationship: Use an interface when you want to define a behavior that can be shared across unrelated classes. For example, both a Bird and a Plane can Fly(), but they aren't the same type of thing. ii) Multiple Inheritance: Since most languages don't allow a class to inherit from multiple parents, interfaces allow a class to "plug in" to many different behaviors. iii) Decoupling: Use interfaces when you want to swap out implementations easily (like switching between a SQLDatabase and a MongoDatabase without changing your main logic). 👉Code explanation: 1. Abstract Class: The "Partial" Blueprint: abstract class Animal { String name; // Constructor: Abstract classes can have them! Animal(String name) { this.name = name; } // Concrete method: All animals breathe the same way here void breathe() { System.out.println(name + " is breathing air."); } // Abstract method: No code here! Subclasses MUST decide the sound. abstract void makeSound(); } 👉2. Interface: The "Plug-in" Ability interface Swimmable { void swim(); // Interfaces usually only define "what", not "how" } interface Playful { void play(); } 👉3. The implementation: Here is how a Dog brings it all together. It is an Animal and it is Swimmable and Playful. // A Dog "extends" the base class and "implements" the abilities class Dog extends Animal implements Swimmable, Playful { Dog(String name) { super(name); // Passes the name up to the Animal constructor } // We MUST implement this because of the abstract class @Override void makeSound() { System.out.println("Woof! Woof!"); } // We MUST implement these because of the interfaces @Override public void swim() { System.out.println(name + " is doing the doggy paddle."); } @Override public void play() { System.out.println(name + " is chasing a ball."); } }
To view or add a comment, sign in
-
-
*⚡ Control Flow in Java (if-else & switch)* *✅ 1️⃣ What is Control Flow?* 👉 Control Flow determines which code runs and when. Example: If condition is true → do this Else → do something else *✅ 2️⃣ if Statement* Used when you want to execute code only if a condition is true. if (condition) { // code } Example: int age = 20; if (age >= 18) { System.out.println("You can vote"); } *✅ 3️⃣ if-else Statement* Used when you want two outcomes. if (condition) { // true block } else { // false block } Example: int age = 16; if (age >= 18) { System.out.println("Adult"); } else { System.out.println("Minor"); } *✅ 4️⃣ if-else if Ladder* Used when you have multiple conditions. int marks = 85; if (marks >= 90) { System.out.println("A Grade"); } else if (marks >= 75) { System.out.println("B Grade"); } else if (marks >= 50) { System.out.println("C Grade"); } else { System.out.println("Fail"); } *🔥 Important Rule ⭐* 👉 Conditions are checked top to bottom 👉 First true condition executes → rest are skipped *✅ 5️⃣ Nested if* 👉 if inside another if int age = 20; boolean hasID = true; if (age >= 18) { if (hasID) { System.out.println("Allowed"); } } *✅ 6️⃣ switch Statement* Used when you have multiple fixed values. 👉 Cleaner than multiple if-else switch (variable) { case value1: // code break; case value2: // code break; default: // code } Example: int day = 2; switch (day) { case 1: System.out.println("Monday"); break; case 2: System.out.println("Tuesday"); break; default: System.out.println("Invalid"); } *🔥 Important Concepts (switch ⭐)* 1️⃣ break keyword 👉 Stops execution after a case Without break: case 1: System.out.println("Monday"); case 2: System.out.println("Tuesday"); 👉 Output: Monday Tuesday 2️⃣ default case 👉 Runs when no case matches *✅ 7️⃣ When to Use What?* - Simple condition: Use if - Two outcomes: Use if-else - Multiple conditions: Use if-else if - Fixed values: Use switch *🔥 Example Program* 👉 This program performs two tasks: 1️⃣ Checks whether a number is positive or negative 2️⃣ Prints the day based on a number using switch class ControlFlowDemo { public static void main(String[] args) { int number = 10; if (number > 0) { System.out.println("Positive"); } else { System.out.println("Negative"); } int day = 1; switch (day) { case 1: System.out.println("Monday"); break; default: System.out.println("Other day"); } } } ✔ Checks number → Positive/Negative ✔ Uses switch → prints day ✔ Uses break → stops execution ✔ Uses default → fallback *⭐ Common Interview Questions* - Difference between if-else and switch - When to use switch over if - What happens if break is missing? - Can we use String in switch? (👉 Yes, Java 7+)
To view or add a comment, sign in
-
*⚡ Control Flow in Java (if-else & switch)* *✅ 1️⃣ What is Control Flow?* 👉 Control Flow determines which code runs and when. Example: If condition is true → do this Else → do something else *✅ 2️⃣ if Statement* Used when you want to execute code only if a condition is true. if (condition) { // code } Example: int age = 20; if (age >= 18) { System.out.println("You can vote"); } *✅ 3️⃣ if-else Statement* Used when you want two outcomes. if (condition) { // true block } else { // false block } Example: int age = 16; if (age >= 18) { System.out.println("Adult"); } else { System.out.println("Minor"); } *✅ 4️⃣ if-else if Ladder* Used when you have multiple conditions. int marks = 85; if (marks >= 90) { System.out.println("A Grade"); } else if (marks >= 75) { System.out.println("B Grade"); } else if (marks >= 50) { System.out.println("C Grade"); } else { System.out.println("Fail"); } *🔥 Important Rule ⭐* 👉 Conditions are checked top to bottom 👉 First true condition executes → rest are skipped *✅ 5️⃣ Nested if* 👉 if inside another if int age = 20; boolean hasID = true; if (age >= 18) { if (hasID) { System.out.println("Allowed"); } } *✅ 6️⃣ switch Statement* Used when you have multiple fixed values. 👉 Cleaner than multiple if-else switch (variable) { case value1: // code break; case value2: // code break; default: // code } Example: int day = 2; switch (day) { case 1: System.out.println("Monday"); break; case 2: System.out.println("Tuesday"); break; default: System.out.println("Invalid"); } *🔥 Important Concepts (switch ⭐)* 1️⃣ break keyword 👉 Stops execution after a case Without break: case 1: System.out.println("Monday"); case 2: System.out.println("Tuesday"); 👉 Output: Monday Tuesday 2️⃣ default case 👉 Runs when no case matches *✅ 7️⃣ When to Use What?* - Simple condition: Use if - Two outcomes: Use if-else - Multiple conditions: Use if-else if - Fixed values: Use switch *🔥 Example Program* 👉 This program performs two tasks: 1️⃣ Checks whether a number is positive or negative 2️⃣ Prints the day based on a number using switch class ControlFlowDemo { public static void main(String[] args) { int number = 10; if (number > 0) { System.out.println("Positive"); } else { System.out.println("Negative"); } int day = 1; switch (day) { case 1: System.out.println("Monday"); break; default: System.out.println("Other day"); } } } ✔ Checks number → Positive/Negative ✔ Uses switch → prints day ✔ Uses break → stops execution ✔ Uses default → fallback *⭐ Common Interview Questions* - Difference between if-else and switch - When to use switch over if - What happens if break is missing? - Can we use String in switch? (👉 Yes, Java 7+) *🔥 Quick Revision* if → single condition if-else → two outcomes if-else if → multiple conditions
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development