🛡️🧩 GUARDED PATTERNS WITH WHEN IN JAVA (JDK 21+) 🔸 TLDR Guarded patterns let you add a boolean condition to a pattern case using when, so you can express type + rule in one place inside a switch. Cleaner than nested if chains ✅ 🔸 THE PROBLEM (JAVA 8 STYLE) You match the type… then you nest another if for the condition. It works, but it gets noisy fast 😵💫 if (shape instanceof Circle c) { if (c.radius() > 10) { return "large circle"; } else { return "small circle"; } } else { return "not a circle"; } 🔸 THE MODERN WAY (JAVA 21+) Same logic, but expressed declaratively: “if it’s a Circle and radius > 10…” 🎯 return switch (shape) { case Circle c when c.radius() > 10 -> "large circle"; case Circle c -> "small circle"; default -> "not a circle"; }; 🔸 WHY WHEN IS A BIG WIN ▪️ 🎯 PRECISE MATCHING — Type + condition in a single case label ▪️ 📐 FLAT STRUCTURE — No nested branching inside a case ▪️ 📖 READABLE INTENT — Reads almost like English (“case Circle when radius > 10”) ▪️ 🧼 EASIER TO EXTEND — Add more guarded cases without turning code into a maze 🔸 TAKEAWAYS ▪️ ✅ Use when to refine a pattern match with a boolean condition ▪️ ✅ Prefer guarded cases over “case + nested if” for readability ▪️ ✅ Great fit for classification logic (rules, routing, categorization) ▪️ ⚠️ Order matters: the first matching case wins, so put more specific guards first #Java #Java21 #PatternMatching #SwitchExpression #CleanCode #Refactoring #SoftwareEngineering #JVM Go further with Java certification: Java👇 https://lnkd.in/eZKYX5hP Spring👇 https://lnkd.in/eADWYpfx SpringBook👇 https://bit.ly/springtify JavaBook👇 https://bit.ly/jroadmap src: https://lnkd.in/gKmcDm3h
Vincent Vauban’s Post
More Relevant Posts
-
Your container keeps restarting from OOM (out of memory), but the Java heap looks fine? Before you go all-in on a heap leak, check your threads. I have seen this in containerized Java services: memory creeps up over hours or days, the container hits its limit, gets killed, then restarts. No dramatic spike, just a slow climb. Threads can drive that climb because they use native memory for stacks (plus per-thread overhead), which will not show up as “heap used”. Mini playbook (5-minute triage): 1) Confirm the restart reason matches the memory limit. 2) Get a shell into the running container. 3) Find the Java PID (try `jcmd -l`). 4) Run: `jcmd <pid> Thread.print` 5) Scan for: - a surprisingly high total thread count - repeating thread names or pools that keep growing - many similar stacks pointing to thread creation (`new Thread(...)`, `Executors.new*`, schedulers, custom thread factories) If the thread count keeps increasing, treat it like a leak: - bound pools and queues - reuse executors instead of creating new ones - shut them down on lifecycle events The nice part is that `Thread.print` often points to the code path creating threads, which is faster than guessing from memory graphs alone. What’s your go-to move when a container is OOM-killed: thread dump first, heap dump first, or something else? #java #kubernetes #observability #performance #memory #jvm
To view or add a comment, sign in
-
-
🚀 Java Deep Dive — Daemon Threads (Something many developers overlook) In Java, not all threads behave the same way. There are two types: • User Threads • Daemon Threads The JVM keeps running as long as at least one user thread is alive. But daemon threads work differently. They are background service threads used for supporting tasks like: • Garbage Collection • Monitoring • Background cleanup If all user threads finish, the JVM will terminate immediately, even if daemon threads are still running. Example: Java Example Thread thread = new Thread(() -> { while(true){ System.out.println("Running..."); } }); thread.setDaemon(true); thread.start(); If the main thread finishes, this daemon thread will not keep the JVM alive. Important rule: You must call "setDaemon(true)" before starting the thread, otherwise Java throws "IllegalThreadStateException". 💡 Key Insight Daemon threads are useful for background tasks that should not block application shutdown. #Java #Multithreading #BackendDevelopment #SoftwareEngineering #LearningInPublic
To view or add a comment, sign in
-
Blog: Some Benefits of Enabling Compact Object Headers in Java 25 for Streams There are signs. You just have to learn how to look for and read them. https://lnkd.in/e4ARCGbQ
To view or add a comment, sign in
-
💥☕ Troubleshooting OutOfMemoryError in Java Few things are more stressful in production than seeing: java.lang.OutOfMemoryError 😱 But OOM is not just “a memory issue” - it’s usually a design, configuration, or resource management problem hiding underneath 🔍 In my latest blog, I break down the most common types of OOM errors and their real-world causes 👇 📘 What You Will Learn 🧠 1️⃣ Java heap space Common causes of heap memory leaks: 📦 Static fields holding references ⚖️ Incorrect equals() / hashCode() implementations 🧩 Non-static inner classes 🗑️ Misuse of finalize() 🔌 Unclosed streams & database connections 🧵 Improper use of ThreadLocal in thread pools ♻️ 2️⃣ GC Overhead Limit Exceeded When the JVM spends too much time doing GC and recovers too little memory 🧱 3️⃣ Metaspace Class metadata leaks and excessive class loading 📏 4️⃣ Requested Array Size Exceeds VM Limit When allocation size itself becomes the issue 🚀 5️⃣ Direct Buffer Memory Off-heap memory issues (often seen in NIO / Netty applications) Understanding these different OOM scenarios helps you move from panic mode to structured diagnosis 💡 🔗 https://lnkd.in/eGWh9K2X Happy debugging - and may your heap stay healthy and your GC stay calm 😄🔥 #Java #JavaDeveloper #JVM #OutOfMemoryError #MemoryLeak #PerformanceTuning #GarbageCollection #Troubleshooting #BackendDevelopment #SoftwareEngineering #TechBlog #LearnJava #DevCommunity
To view or add a comment, sign in
-
-
🚀 Sealed Classes + Records in Java — Clean Code or Just Hype? Java 17+ introduced Sealed Classes and Records, and honestly, together they solve two very real problems we’ve all faced: 👉 Uncontrolled inheritance 👉 Boilerplate-heavy data classes 🔒 Sealed Classes — Finally, Control Over Who Can Extend public sealed interface Payment permits CardPayment, UpiPayment {} This ensures: ✔️ Only defined types can implement your interface ✔️ No unexpected extensions ✔️ Safer and more predictable domain models 📦 Records — Say Goodbye to Boilerplate public record CardPayment(String cardNumber) implements Payment {} public record UpiPayment(String upiId) implements Payment {} ✔️ Immutable by default ✔️ No getters / constructors / equals / hashCode needed ✔️ Perfect for DTOs, APIs, event-driven systems ⚡ Together — This is Where It Gets Interesting Sealed → controlled hierarchy Record → immutable data switch(payment) { case CardPayment c -> System.out.println(c.cardNumber()); case UpiPayment u -> System.out.println(u.upiId()); } 💡 The compiler knows all possible types → fewer bugs, cleaner logic 🤔 Now I’m curious… Are you using sealed classes in your projects? Where exactly? Have records replaced your DTOs, or are you still relying on Lombok/classes? Any real-world challenges with Spring Boot, JPA, or serialization? 👇 Would love to hear how you’re using these features in production #Java #Java17 #SealedClasses #Records #CleanCode #JavaDeveloper #BackendDevelopment #SoftwareEngineering #Microservices #APIDesign #CodingBestPractices #TechDiscussion
To view or add a comment, sign in
-
-
In Java, _ was just a bad variable name. Now it's a feature. 🤯 Most developers don't know this: the underscore _ has been through a full lifecycle in Java — valid, deprecated, illegal, and reborn. Here's the full story: ✅ Java 8: int _ = 5; → compiles fine ☠️ Java 9 — _ becomes a warning ⚠️ Java 9: same line → "warning: '_' is a keyword" ❌ Java 11 — full error int _ = 5; → compilation error The language spec officially killed it as an identifier. ✅ Java 21 — Unnamed Variables (JEP 456) _ is back, but now it has a purpose: signal that you intentionally don't care about a value. Real-world use cases: → Catch blocks you don't need to inspect: try { riskyCall(); } catch (Exception _) { log("failed"); } → Loops where the element doesn't matter: for (var _ : events) { counter++; } → Pattern matching — ignoring parts of a record: if (obj instanceof Point(int x, int _)) { use(x); } Why does this matter? 🎯 Before Java 21, you'd write dummy = something or unused = value — polluting your code with meaningless names. Now _ is a semantic contract: "I know this value exists. I'm choosing not to use it." It's the same philosophy behind _ in Python, Scala, and Kotlin. Clean code isn't just about what you write — it's also about what you intentionally discard. If you're prepping for OCP Java 21 (1Z0-830), unnamed variables are fair game in pattern matching questions. 📊 JEP 456 — Unnamed Variables & Patterns (OpenJDK, 2024) https://lnkd.in/eR-aAMq8 📊 Java 21 Release Notes (Oracle, 2023) https://lnkd.in/eBhDzJUJ 📊 The Java Language Specification — Java SE 21 Edition https://lnkd.in/e5dH-fzw #Java #Java21 #SoftwareEngineering #BackendDevelopment #CleanCode #OCP #JEP456 #CodingTips
To view or add a comment, sign in
-
Day 10 of Java & Now I Know Where My Array Actually Lives 🧠💻 Today was not about writing arrays… It was about understanding what happens inside memory. And honestly this was powerful. 👉 Arrays are non-primitive (reference) types. That means: When we write int[] arr = new int[5]; • The variable arr lives in Stack memory • The actual array data lives in Heap memory • arr stores the reference (address) of that heap location So basically… We’re pointing to memory. 🔥 Contiguous Storage Array elements are stored next to each other in one continuous block. 5 integers = 5 × 4 bytes = 20 bytes All in one straight line. That’s why arrays are fast. ⚡ Random Access Java doesn’t search for elements. It calculates their address: Base Address + (Index × Size of Data Type) That’s why accessing the 1st element takes the same time as the 1,000,000th. O(1) access. Instant. Big realization today? Arrays aren’t just collections. They’re structured memory blocks optimized for speed. Day 10 and now I’m not just using arrays… I understand how they work internally. Leveling up every day 🚀🔥 Special thanks to Rohit Negi sir and Aditya Tandon sir🙌🏻🙌🏻 #Java #CoreJava #Arrays #Programming #LearningJourney #Developers #BuildInPublic
To view or add a comment, sign in
-
-
Metaspace: Where Classes Live 🏠 Ever wondered where your JVM stores the blueprint of your application? It’s not in the Heap. Since Java 8, class metadata (like class names, methods, and field layouts) resides in Metaspace. This is a significant shift from the old PermGen (Permanent Generation) model. Here is why Metaspace matters for your application stability: ⚙️ Native Memory: Unlike the Heap, Metaspace resides in Native Memory (OS memory). It is not part of the Java Heap. 📈 Dynamic Resizing: By default, Metaspace grows automatically. It uses native memory available on your OS, reducing the "java.lang.OutOfMemoryError: PermGen" errors we used to fear. 🔧 Tuning Flags: You can control it with -XX:MaxMetaspaceSize. If you don't set a limit, it will consume as much native memory as your application needs for class loading. The catch? If you are dynamically generating classes (common in frameworks like Spring, Hibernate, or scripting languages), Metaspace usage can explode if not monitored. 3 Common Questions Answered: Q1: Is Metaspace part of the Heap? ❌ No. Metaspace lives outside the Java Heap, in the native memory of the operating system. Q2: Why did Java 8 replace PermGen with Metaspace? The main reason was to improve predictability. PermGen was a fixed-size Heap space and was notoriously difficult to tune, often leading to OutOfMemoryErrors. Metaspace taps into native memory, allowing it to grow dynamically based on the application's actual runtime needs. Q3: How can I monitor Metaspace usage? You can use JVM tools like JConsole, VisualVM, or jstat. Look for the "Non-Heap" memory section, or specifically monitor the Metaspace pool to track loaded classes and memory consumptions. #Java #JVM #Metaspace #Performance #Programming #SoftwareEngineering
To view or add a comment, sign in
-
Something weird happened while I was debugging a Java program today. I had a simple program running with multiple threads, and I printed the thread names just to see what was happening. The output looked something like this: main http-nio-8080-exec-1 http-nio-8080-exec-2 ForkJoinPool.commonPool-worker-3 At first I ignored it. But then I started wondering… Where are all these threads actually coming from? I didn’t create them. After digging a bit deeper, I realized something interesting. Modern Java applications are constantly using different thread pools behind the scenes. For example: • The web server creates request threads • "CompletableFuture" uses the ForkJoinPool • Some frameworks create background worker threads • The JVM itself runs internal service threads Which means even a “simple” backend service may actually be running dozens of threads at the same time. It made me realize something: A lot of complexity in backend systems isn’t in the code we write — it’s in the systems running around our code. Now I’m a lot more curious about what’s actually happening inside the JVM when our apps run. #Java #BackendEngineering #SpringBoot #SoftwareEngineering #LearningInPublic
To view or add a comment, sign in
-
The Hidden Mechanism Behind ThreadLocal in Java ThreadLocal is often explained simply as: “Data stored per thread.” That’s true — but the interesting part is how it actually works internally. Most developers think the data lives inside ThreadLocal. It doesn’t. How ThreadLocal Works Internally Each Thread object maintains its own internal structure: Thread └── ThreadLocalMap ├── ThreadLocal → Value ├── ThreadLocal → Value The important detail: The map belongs to the Thread, not to ThreadLocal. ThreadLocal simply acts as a key. Basic Flow When you call: ThreadLocal.set(value) Internally: Copy code thread = currentThread map = thread.threadLocalMap map.put(ThreadLocal, value) When you call: ThreadLocal.get() It retrieves the value from the current thread’s map. Each thread therefore has its own independent copy. Where This Is Used in Real Systems You’ll find ThreadLocal used in many frameworks: • Spring Security → SecurityContextHolder • Transaction management → TransactionSynchronizationManager • Logging correlation IDs • Request scoped context It allows frameworks to store request-specific data without passing it through every method. The Hidden Danger If you forget to call: Copy code ThreadLocal.remove() You can create memory leaks. Why? Because thread pools reuse threads. Old values may remain attached to long-lived threads. ThreadLocal is simple conceptually. But its internal design is what makes many Java frameworks work efficiently. Have you used ThreadLocal in production code? #Java #CoreJava #Multithreading #ThreadLocal #SpringBoot #BackendEngineering #InterviewPreparation
To view or add a comment, sign in
More from this author
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