💡 Is the finally block losing its importance in modern Java? If you’ve been working with Java for a while, you’ve surely used the finally block — the trusty companion that ensures resources are released no matter what happens in your try block. Example 👇 FileInputStream fis = null; try { fis = new FileInputStream("data.txt"); // process file } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } ✅ The intention was solid — guarantee cleanup, even when exceptions occur. ⚠️ But the problem? The finally block itself can throw exceptions or mask the original one. For example, if fis.close() fails, the real cause of the failure inside try might be lost. That’s why modern Java developers have largely moved away from finally for resource handling. 🚀 Enter try-with-resources (Java 7+) It automatically closes resources that implement AutoCloseable, making your code safer and cleaner. Example 👇 try (FileInputStream fis = new FileInputStream("data.txt")) { // process file safely } catch (IOException e) { e.printStackTrace(); } ✨ Benefits: No need for explicit finally cleanup. Prevents resource leaks. Preserves the original exception. More concise and readable code. So yes — the finally block still exists, but in most cases, it’s been gracefully replaced by try-with-resources, the safer and modern approach. #Java #CodingTips #Developers #CleanCode #JavaProgramming #ExceptionHandling #SoftwareEngineering
Shaahul Hamid’s Post
More Relevant Posts
-
I recently experimented with Virtual Threads in Java 21, and the performance improvement was honestly impressive. For years, Java developers (including me) have been limited by the cost of traditional threads. Each thread maps directly to an OS thread, which consumes a lot of memory and doesn’t scale well for high concurrency. With Virtual Threads, that model changes completely. These are lightweight, JVM-managed threads that allow you to create tens or even hundreds of thousands of concurrent tasks — without killing performance or memory. What I tested: I wrote a small program that performs 10,000 HTTP GET requests to an external test endpoint using the standard HttpClient with blocking I/O. I ran it twice — once with regular threads, once with virtual threads. The results: Platform threads (traditional): 1,000 requests → ~25 seconds, ~600 MB memory 10,000 requests → Failed (OutOfMemoryError) Virtual threads (Java 21): 1,000 requests → ~3 seconds, ~200 MB memory 10,000 requests → ~5 seconds, ~350 MB memory That’s roughly a 5x–10x improvement in time and efficiency. The JVM handled thousands of concurrent blocking operations smoothly. What I learned: Virtual Threads are perfect for I/O-bound workloads (like HTTP or database calls). Using Virtual Threads in Java 21 can significantly improve scalability and reduce infrastructure costs, saving a lot of money for the company by handling more concurrent requests with fewer servers and lower resource usage. You can write simple, blocking-style code that scales like async code. The code is cleaner, easier to read, and performs far better under load. For CPU-heavy tasks, platform threads or fixed pools are still better. This feels like a big step forward for Java. With frameworks like Spring Boot 3.2+ already adding support for Virtual Threads, I can see this becoming the default way to write scalable backends. If you haven’t tried it yet, I highly recommend experimenting with it. You might be surprised how much performance and simplicity you gain — without rewriting your code.
To view or add a comment, sign in
-
🚀 When Java’s HashMap Switches from Linked List to Balanced Tree — and Why It Matters! Did you know that Java’s HashMap got smarter since Java 8? 😎 When multiple keys land in the same hash bucket (due to hash collisions), older versions of Java stored them in a linked list — giving O(n) lookup time in the worst case. But Java 8+ said: “Let’s fix that!” 🔧 Here’s what happens now 👇 ✅ If a bucket gets 8 or more entries, it’s converted from a LinkedList to a Balanced Red-Black Tree. ✅ This makes lookups much faster — turning worst-case O(n) into O(log n). ✅ If the number of entries later drops below 6, it switches back to a linked list. ✅ Treeification only happens when the map capacity is at least 64 — otherwise, it just resizes. 💡 Performance insight: You’ll almost never notice this change in everyday use — because good hash distribution keeps buckets small. But it’s a great defensive design that keeps your application safe from performance drops or hash-collision attacks. 🔍 Pro tips for developers: Always implement a strong hashCode() for custom objects. Initialize maps with a sensible capacity if you know their expected size. Remember, this feature doesn’t replace good design — it’s just a safety net! 📊 In short: Java 8’s HashMap automatically switches to a red-black tree when collisions get heavy, improving lookup speed from O(n) → O(log n). #Java #SpringBoot #HashMap #Coding #Performance #Java8 #DeveloperTips #TechLearning
To view or add a comment, sign in
-
💡 Immutability in Java — why it matters and how to use it effectively Immutability is one of those concepts that makes your Java code safer, cleaner, and easier to reason about. But what does “immutable” really mean? 👇 🧩 What is immutability? An immutable object is one whose state cannot change after it’s created. Once you build it, its data stays the same forever. This prevents unexpected side effects, race conditions, and bugs caused by shared mutable state — especially in multithreaded systems. 🧠 The classic example: String All String objects in Java are immutable. The classic example: String All String objects in Java are immutable String name = "Java"; name.concat(" Rocks!"); System.out.println(name); // "Java" ✅ Even though we called .concat(), it didn’t modify the original string. It returned a new String. ⚙️ final keyword Declaring a variable as final means you can’t reassign the reference — but it doesn’t make the object itself immutable. final List<String> list = new ArrayList<>(); list.add("A"); // ✅ allowed list = new ArrayList<>(); // ❌ not allowed 🧱 record — immutability made easy Since Java 16, record is the easiest way to create immutable data carriers: public record Person(String name, int age) {} Records automatically make fields private and final, and generate constructors, getters, equals(), hashCode(), and toString(). No setters. No mutability. Pure data. 🚀 Why use immutability Makes code thread-safe without synchronization Easier to debug and test Predictable state — no “who changed this object?” moments Simplifies functional programming with Streams and Lambdas 💬 Conclusion: String → always immutable final → prevents reassignment, not mutation record → immutable data structure made simple Immutability is not about restrictions — it’s about predictability and safety. #Java #Backend #CleanCode #Programming #SpringBoot #SoftwareEngineer #DeveloperTip
To view or add a comment, sign in
-
💡Ever used Optional in Java thinking it would magically eliminate NullPointerExceptions? I did — and it turned into a small coding disaster (and a big learning moment). 😅 In my latest Medium blog, I’ve shared what really happened when I used Optional in my code — what went wrong, how I fixed it, and the best practices I follow today to write cleaner, safer code in Java. 🧩 Check it out here 👇 🔗 https://lnkd.in/ggZymaP9
To view or add a comment, sign in
-
💡Practical Use of Java 8 Streams — Think Beyond Just Loops Ever found yourself writing long loops just to filter or transform data from a list? That’s where Java 8 Streams shine — clean, readable, and efficient. Let’s look at a real-world example 👇 Imagine you have a list of employees and you want to: • Get all employees earning more than ₹50,000 • Sort them by salary (descending) • Collect just their names Before Java 8: List<String> result = new ArrayList<>(); for (Employee e : employees) { if (e.getSalary() > 50000) { result.add(e.getName()); } } Collections.sort(result); With Streams: List<String> result = employees.stream() .filter(e -> e.getSalary() > 50000) .sorted(Comparator.comparing(Employee::getSalary).reversed()) .map(Employee::getName) .collect(Collectors.toList()); ✅ Readable – you describe what to do, not how to do it ✅ Chainable – each step flows like a pipeline ✅ Parallelizable – add .parallelStream() for large datasets Key takeaway: Streams make your code more declarative, concise, and less error-prone. Once you start using them, you’ll rarely go back to old-style loops. Question for you 👇 What’s one Stream operation you use the most — filter, map, or collect? #Java #Programming #Streams #Java8 #CleanCode #CodingTips
To view or add a comment, sign in
-
The Secret Life of Java’s Garbage Collector You write code. You create objects. But do you ever wonder what happens to them after you stop using them? Java has a silent worker running behind the scenes — the Garbage Collector (GC). It cleans up memory so you don’t have to. Here’s how it works in simple terms: 1. The Nursery (Young Generation) New objects are born here. Most don’t live long. GC sweeps this area often — fast and frequent. 2. The Tenured Space (Old Generation) Objects that survive longer move here. GC checks this area less often, but when it does, it’s heavier work. 3. The Metaspace Stores class metadata, not objects. It replaced the old PermGen space in Java 8. Different GC algorithms you should know Serial GC: Simple and single-threaded. Best for small apps. Parallel GC: Uses multiple threads for cleanup. Good balance for most systems. G1 GC: Modern, low-latency collector. Ideal for large heaps and production use. ZGC & Shenandoah: Advanced, near-zero pause collectors for real-time performance. How to check your GC in use: Run your app with: java -XX:+PrintCommandLineFlags -version It’ll show the default GC used. Why it matters Knowing your GC type helps you tune performance when memory pressure grows. You don’t have to be an expert, but you should know what keeps your JVM healthy. Memory issues are rarely random — they’re signals from a GC working too hard. What GC do you usually rely on for production Java apps? #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment
To view or add a comment, sign in
-
The humble switch statement has come a long way from its early days in Java. What began as a simple control structure has evolved into a powerful, expressive feature — shaping how developers write cleaner, more readable code. https://lnkd.in/dg3VWGWG
To view or add a comment, sign in
-
In #Java, a class can have a field of the Collection type. When we create a new object of the class, we need to take few extra steps to handle Collection fields in a safe manner. You may say, wait a minute, the elements of my Collection, are immutable objects! Because they are implemented as Java records, or whatever technique you use to implement an immutable class. That simplifies the problem, but doesn't completely eliminate it. And the problem here is that the collection itself may not be an immutable object, what means that other parts of the application can hold the same collection reference and accidentally modify the collection in a way that wasn't expected by our custom class. The solution to this is to create a new reference for the collection and do defensive copy for all the elements. If we are using immutable elements, that solves the second part, we don't need to defensively copy immutable objects because they can't change. Regarding the first part, the quickest solution would be to use 𝐋𝐢𝐬𝐭.𝐜𝐨𝐩𝐲𝐎𝐟() method that will create a new list reference. But if you read the method documentation, you will see that this method will create an unmodifiable list, which doesn't support NULL list elements. So to bulletproof the logic, it's better to first filter out all null elements, and only after that return a new collection instance. If you use Stream API and its toList() method, it will return an unmodifiable list. Below code uses Java record compact constructor to create a new collection reference when instantiating an object:
To view or add a comment, sign in
-
-
I wrote an article about Java classes—still in wide use today—that have had better replacements available for more than ten years and, in some cases, almost 30 years. I explain some of the problems with the old classes and what to use instead. Your code maintainers will thank you for using the replacement classes. https://lnkd.in/gRTyssRR
To view or add a comment, sign in
-
🚀 Java 21 Virtual Threads: Why They’re a Game-Changer — and What You MUST Change Before Adopting Them Java 21 introduced Virtual Threads (Project Loom) — one of the biggest shifts in Java concurrency in 20+ years. If you’re still depending on heavy thread pools or reactive frameworks for scalability, it’s time to rethink. ⸻ 🔍 What Are Virtual Threads? They’re lightweight threads managed by the JVM — not the OS. You can run hundreds of thousands of them without exhausting system resources. In simple terms: 👉 Virtual Threads = Blocking operations without blocking the system. 👉 Perfect for I/O-heavy apps: APIs, DB calls, messaging, file I/O. ⸻ ⚙️ How They Work When a virtual thread hits a blocking call, the JVM: 1️⃣ Detaches it from the OS thread 2️⃣ Frees the OS thread for other work 3️⃣ Reattaches and resumes when I/O completes No callbacks. No reactive complexity. Just clean synchronous code — with massive scalability. ⸻ 💡 Why Adopt Them? ✔ Fewer thread-pool headaches ✔ Simplified async logic ✔ Higher throughput & lower latency ✔ Works with existing synchronous code ✔ Easier debugging than reactive stacks ⸻ 🛠 Before Adopting Virtual Threads, Fix These: ✅ 1. Remove large fixed thread pools Use: Executors.newVirtualThreadPerTaskExecutor() ✅ 2. Avoid heavy ThreadLocal usage Replace with Scoped Values (Java 21) or pass context explicitly. ✅ 3. Audit blocking calls Good: JDBC, HTTP clients, network I/O Avoid: JNI, long synchronized blocks, old drivers ✅ 4. Move away from forced-reactive frameworks Virtual threads let you return to simple synchronous logic. ✅ 5. Update your server stack Spring Boot 3.2+, Tomcat 10.1+, Jetty 12+, Quarkus/Micronaut latest versions. ⸻ ✨ The Impact Teams adopting virtual threads report: ✔ Higher throughput ✔ Lower latency under load ✔ Simpler, cleaner code ✔ Less reactive boilerplate ✔ No more tuning thread pools ⸻ 🔚 Final Thought Virtual Threads aren’t just an optimization — they redefine how we build scalable Java applications. Preparing your codebase now will pay off immediately as you adopt Java 21.
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