Do You Really Need the Entire JDK to Print “Hello World”? In Java 8: Simple hello world program → 210 MB runtime In Java 25: Same program → 47 MB modular runtime I tried executing the below program on two different Java versions( java 8 and java 25): public class JPMSPOCExample { public static void main(String[] args) { System.out.println("Hello JPMS"); } } That’s it. No SQL. No XML. No Networking. Just a simple main(). 🔹 Java 8 Runtime Reality On my system: • Full JRE size → 210 MB • rt.jar inside JRE → ~60 MB Even this tiny program implicitly depended on the entire runtime. That included: java.sql java.desktop java.rmi XML APIs and many other modules There was no way to trim unused parts. Everything was bundled together inside rt.jar. 🔹 Java 25 + JPMS + jlink Now let’s see what happens in Java 25. Step 1 — Compile javac JPMSPOCExample.java Step 2 — Create JAR jar --create --file jpmspoc.jar JPMSPOCExample.class Step 3 — Detect Required Modules jdeps --print-module-deps jpmspoc.jar Output: java.base That’s it. The program only needs java.base. Step 4 — Create Minimal Runtime jlink --add-modules java.base --output minimal-runtime The above creates a folder called "minimal-runtime" Minimal runtime size on my system → 47 MB Step 5 — Run Using Custom Runtime minimal-runtime/bin/java -cp jpmspoc.jar JPMSPOCExample Output: Hello JPMS Conclusion : Simple Hello world program using java 8 requires 210 MB runtime , whereas on java 25 using jlink takes 47 MB modular runtime Now let’s translate that into enterprise impact. 1️⃣ Smaller Docker Images In enterprise environments, If your base image shrinks by ~160 MB: ▪️Faster image pull in Kubernetes ▪️Faster CI/CD pipeline ▪️Faster scaling In large clusters (100+ pods), this becomes significant. Even saving 100 MB per container × 200 pods = 20 GB less transfer during scaling events. Architectural Takeaway Adopting JPMS at the application level is a structural decision. As discussed in my previous post, for many Spring-based REST backends, full modularization may not deliver proportional benefits due to heavy reflection usage. However , Even if we do not introduce module-info.java in our codebase, we should still understand the modular structure of the JDK we are running on. At minimum, we should: • Use jdeps to identify the exact modules our application depends on • Use jlink to build a runtime image that includes only those modules • Avoid shipping unnecessary parts of the JRE into production Note - Jlink will not be useful,If JDK is pre-installed on your prod environment Have you leveraged jlink to build trimmed runtime images in production environments? I’d genuinely love to hear from the community — Did it translate into measurable improvements in: • Container image size? • Startup latency? • Memory footprint? • Overall infrastructure efficiency? Real-world feedback would be extremely valuable. #Java #SpringBoot #SoftwareArchitecture #BackendDevelopment #JPMS #JLink
Java 8 vs Java 25: Shrinking Runtime Sizes with JPMS
More Relevant Posts
-
#Java 8 #Stream #API 🔹 1. What is Stream API? 👉 Stream API is a feature introduced in Java 8 to process collections of data (List, Set, Map) easily using a functional style. 📌 Simple words: Stream API helps to filter, sort, map, and process data in a short and clean way. ✅ Instead of writing long loops, we use stream methods. Example idea: Collection → Stream → Operations → Result 🔹 2. Why Stream API came? (Reason) 🤔 Before Java 8, developers used loops to process collections. ❌ Problems with old approach: More code Hard to read Hard to parallel process Less functional programming ✅ Stream API solved this by: Reducing code Making code readable Supporting parallel processing 🔹 3. Need of Stream API 🎯 Stream API is needed when we want to: 📊 Process large data collections 🔎 Filter data 🔁 Transform data ⚡ Perform operations faster 🧹 Write clean and short code 🔹 4. Advantages of Stream API 🚀 ✅ 1. Less Code No need for long loops. ✅ 2. Readable Code Code becomes clean and understandable. ✅ 3. Functional Programming Supports lambda expressions. ✅ 4. Parallel Processing We can process data faster using parallel streams. ✅ 5. Easy Data Processing Filtering, mapping, sorting becomes simple. 🔹 5. Common Stream Operations ⚙️ Operation Use 🔎 filter() Select specific data 🔁 map() Transform data 📊 sorted() Sort data 📉 limit() Limit results 📦 collect() Convert result to list/set 🔢 count() Count elements 🔹 6. Example (Without Stream API) ❌ List<String> names = Arrays.asList("Ravi","Amit","Ranjit","Raj"); for(String name : names){ if(name.startsWith("R")){ System.out.println(name); } } Problem: More lines Less readable 🔹 7. Example (Using Stream API) ✅ List<String> names = Arrays.asList("Ravi","Amit","Ranjit","Raj"); names.stream() .filter(name -> name.startsWith("R")) .forEach(System.out::println); ✔ Short code ✔ Easy to read ✔ Functional style 🔹 8. Real Time Example (Employee Filtering) 🧑💻 List<Integer> salary = Arrays.asList(20000,50000,30000,70000); salary.stream() .filter(s -> s > 30000) .forEach(System.out::println); 👉 Output 50000 70000 Meaning: Only salaries greater than 30000 are printed. 🔹 9. Stream API Flow 🔄 Collection → stream() → filter/map → collect()/forEach → Result Example Flow: List → Stream → Filter → Map → Collect → Result ✅ In One Line: 👉 Stream API is used to process collection data in a simple, clean, and functional way.
To view or add a comment, sign in
-
🚀 🍃 𝗦𝗽𝗿𝗶𝗻𝗴 𝗕𝗼𝗼𝘁 𝟰 𝗠𝗲𝗲𝘁𝘀 𝗝𝗮𝗰𝗸𝘀𝗼𝗻 𝟯 — 𝗔 𝗡𝗲𝘄 𝗘𝗿𝗮 𝗳𝗼𝗿 𝗝𝗦𝗢𝗡 𝗣𝗿𝗼𝗰𝗲𝘀𝘀𝗶𝗻𝗴 𝗶𝗻 𝗝𝗮𝘃𝗮 For years, Java developers have battled “boilerplate fatigue” when mapping Java objects ↔ JSON. Common frustrations: • Checked exceptions in streams • Mutable ObjectMapper configuration • Verbose serialization setup But the Modern Java Renaissance is here. With Spring Framework 7 and Spring Boot 4 on the horizon, the ecosystem is evolving toward a cleaner, more functional, and concurrency-friendly future. At the center of this shift lies 𝗝𝗮𝗰𝗸𝘀𝗼𝗻 𝟯 ⚙️ 𝗔 𝗡𝗲𝘄 𝗕𝗮𝘀𝗲𝗹𝗶𝗻𝗲: 𝗝𝗗𝗞 𝟭𝟳+ Jackson 3 raises the baseline to Java 17, unlocking modern language capabilities and allowing frameworks like Spring to simplify APIs and remove legacy constraints. Result: a leaner and more modern JSON processing model. 🧩 𝗧𝗵𝗲 “𝗥𝗼𝗼𝗺 𝗳𝗼𝗿 𝗧𝘄𝗼” 𝗦𝘁𝗿𝗮𝘁𝗲𝗴𝘆 A key decision in Spring Boot 4: Jackson 2 and Jackson 3 can coexist on the classpath when using spring-boot-starter-webmvc • Jackson 3 → tools.jackson.* • Annotations stay in com.fasterxml.jackson.* This enables: ✅ Existing models to keep working ✅ Third-party libraries to stay compatible ✅ Gradual ecosystem migration 🧱 𝗜𝗺𝗺𝘂𝘁𝗮𝗯𝗹𝗲 & 𝗧𝗵𝗿𝗲𝗮𝗱-𝗦𝗮𝗳𝗲 𝗖𝗼𝗻𝗳𝗶𝗴 Jackson 2’s ObjectMapper was mutable, which could lead to subtle concurrency issues. Jackson 3 introduces JsonMapper with an immutable builder pattern. Once built, configuration cannot change. ✔ Thread-safe by design ✔ No runtime config mutation ✔ Better fit for modern concurrent Java ⚡𝗟𝗮𝗺𝗯𝗱𝗮-𝗙𝗿𝗶𝗲𝗻𝗱𝗹𝘆 𝗘𝗿𝗿𝗼𝗿 𝗛𝗮𝗻𝗱𝗹𝗶𝗻𝗴 Using JSON inside Java Streams used to be painful because of checked exceptions. Before: IOException and JsonProcessingException forced developers into verbose try/catch blocks. Jackson 3 introduces JacksonException, an unchecked runtime exception. ✔ Cleaner lambda expressions ✔ Stream pipelines without boilerplate ✔ Centralized error handling 📅 𝗛𝘂𝗺𝗮𝗻-𝗥𝗲𝗮𝗱𝗮𝗯𝗹𝗲 𝗗𝗮𝘁𝗲𝘀 𝗯𝘆 𝗗𝗲𝗳𝗮𝘂𝗹𝘁 Jackson 3 switches the default from epoch timestamps → ISO-8601 strings. ✔ Human-readable ✔ Standardized across APIs ✔ No custom serializers needed for most frontend apps 🌐 𝗖𝗹𝗲𝗮𝗻𝗲𝗿 𝗔𝗣𝗜𝘀 𝘄𝗶𝘁𝗵 𝗥𝗲𝘀𝘁𝗖𝗹𝗶𝗲𝗻𝘁 𝗮𝗻𝗱 𝗝𝗦𝗢𝗡 𝗩𝗶𝗲𝘄𝘀 Spring Boot 4 integrates JSON Views directly with RestClient using hint(), removing the need for wrappers like MappingJacksonValue. The result? ✔ One model → multiple API views ✔ Cleaner API design ✔ No DTO explosion 💡 𝗙𝗶𝗻𝗮𝗹 𝗧𝗵𝗼𝘂𝗴𝗵𝘁𝘀 The adoption of Jackson 3 in Spring Boot 4 is more than a version upgrade. It reflects the modernization of the Java ecosystem: • Immutable configuration • Safer concurrency • Functional-friendly exceptions • Better serialization defaults • Cleaner API design Less friction. More focus on building great applications. #Java #SpringBoot4 #Jackson3 #SpringFramework #Java #JSONMapper #RestAPI #JSON #SpringBoot
To view or add a comment, sign in
-
-
🧠 Understanding HashMap Internals — Collision, Load Factor & Bucket Size (Java Deep Dive) If you’ve used HashMap in Java, you probably know it’s fast. But why is it fast? And what actually happens under the hood when things go wrong? 🤔 Let’s break down three core concepts that every backend developer should understand 👇 🔹 1. Collision — When Two Keys Fight for the Same Spot A collision happens when two different keys generate the same hash index. index = hash(key) % bucketSize; 👉 Different keys → Same index → Collision 💥 What happens internally? Before Java 8 → Stored as a Linked List. Java 8+ → Converts to a Balanced Tree (Red-Black Tree) if collisions grow ⚠️ Why it matters: More collisions = more time to search → O(n) instead of O(1). 🔹 2. Load Factor — The Resize Trigger Load Factor defines how full the HashMap can get before resizing. loadFactor = size / capacity Default value in Java: 👉 0.75 💡 What it means: If capacity = 16 Resize happens when size > 12 🔄 What happens during resize? Capacity doubles (16 → 32 → 64…) All entries are rehashed Expensive operation ⚠️ ⚖️ Trade-off: High load factor → Less memory, more collisions Low load factor → More memory, fewer collisions 🔹 3. Bucket Size — The Foundation Bucket size = number of slots (capacity) in the HashMap 👉 Default initial capacity = 16 Each bucket stores: One node (ideal case) Or multiple nodes (collision case) 📌 Important: Always a power of 2 (16, 32, 64…) Helps optimize index calculation using bit operations 🔄 How Everything Works Together 1️⃣ Key goes through hashCode() 2️⃣ Hash determines bucket index 3️⃣ If empty → insert 4️⃣ If collision → chain/tree 5️⃣ If threshold crossed → resize ⚡ Performance Summary: 🚀 Best Case → O(1) ⚖️ With Collisions (Java 8+) → O(log n) 🐢 Worst Case → O(n) 🏁 Final Takeaway 👉 HashMap is not just a simple key-value store — it’s a carefully optimized data structure. 👉 Understanding collisions, load factor, and bucket sizing helps you: Write better code Avoid performance pitfalls #Java #HashMap #DataStructures #BackendDevelopment #SystemDesign #JavaInternals #CodingInterview
To view or add a comment, sign in
-
-
🧱 POJO Classes in Java: The Backbone of API Automation In the world of API automation, POJO (Plain Old Java Object) classes are more than just data holders — they’re the foundation of clean, scalable, and maintainable test frameworks. 💡 What is a POJO? A POJO is a simple Java class that encapsulates data without any business logic. It typically includes: Private fields Public getters and setters Optional constructors and toString() 🚀 Use Cases in API Automation Request Payload Modeling Create POJO classes to represent JSON/XML request bodies. Easily serialize using libraries like Jackson or Gson. Response Deserialization Map API responses directly into POJO objects for validation. Example: UserResponse user = response.as(UserResponse.class); Data-Driven Testing Combine POJOs with external data sources (Excel, JSON, DB) for dynamic test execution. Validation & Assertions Use POJO fields to assert response values cleanly. Example: Assert.assertEquals(user.getEmail(), "test@example.com"); 🧠 Integrating Builder Pattern with POJOs The Builder Pattern adds flexibility and readability when constructing complex POJO objects, especially for nested payloads. User user = User.builder() .name("Garima") .email("garima@test.com") .role("Admin") .build(); 🔧 Benefits: Reduces constructor overload Improves code readability Supports immutability Ideal for test data setup ✅ Why It Matters 🧼 Clean Code: Keeps test logic separate from data modeling 🔁 Reusable: POJOs can be reused across multiple test cases 🧪 Test-Friendly: Simplifies assertions and validations 📦 Scalable: Works seamlessly with frameworks like RestAssured 💬 Are you using POJOs + Builder in your API automation framework? Drop your favorite pattern or tip below 👇 #SDET #Automation #AutomationTesting #APIAutomation #Java #Learning #RESTAssured #DesignPattern #POJO #BuilderPattern #QA #InterviewPrep
To view or add a comment, sign in
-
-
𝐂𝐥𝐚𝐬𝐬𝐋𝐨𝐚𝐝𝐞𝐫𝐬 & 𝐌𝐞𝐦𝐨𝐫𝐲 — 𝐉𝐚𝐯𝐚’𝐬 𝐒𝐦𝐚𝐫𝐭 𝐖𝐚𝐫𝐞𝐡𝐨𝐮𝐬𝐞 𝐒𝐲𝐬𝐭𝐞𝐦: Think of the JVM as a fully automated smart warehouse.Before any product (Java class) can be used, it must be located, verified, stored correctly, and tracked. That’s exactly what happens before your Java code even starts executing. 1. 𝐂𝐥𝐚𝐬𝐬𝐋𝐨𝐚𝐝𝐞𝐫 — 𝐓𝐡𝐞 𝐖𝐚𝐫𝐞𝐡𝐨𝐮𝐬𝐞 𝐑𝐞𝐜𝐞𝐢𝐯𝐢𝐧𝐠 𝐓𝐞𝐚𝐦 Before Java can use a class, it must be loaded into the JVM. ClassLoaders: ✔️ Locate .class files ✔️ Verify bytecode ✔️ Load them into memory Types of ClassLoaders (Receiving Zones): 🔹 𝐁𝐨𝐨𝐭𝐬𝐭𝐫𝐚𝐩 𝐂𝐥𝐚𝐬𝐬𝐋𝐨𝐚𝐝𝐞𝐫 • Loads core Java inventory (java.lang.*, java.util.*) • This is the foundation stock — always available 🔹 𝐄𝐱𝐭𝐞𝐧𝐬𝐢𝐨𝐧 𝐂𝐥𝐚𝐬𝐬𝐋𝐨𝐚𝐝𝐞𝐫 • Loads optional, extended packages • Think of specialized add-on supplies 🔹 𝐀𝐩𝐩𝐥𝐢𝐜𝐚𝐭𝐢𝐨𝐧 𝐂𝐥𝐚𝐬𝐬𝐋𝐨𝐚𝐝𝐞𝐫 • Loads your application’s classes • Custom products you bring into the warehouse 🔁 Delegation Model: Each loader checks with its parent first before loading. ➡️ Prevents duplicate inventory and ensures system stability. 2. 𝐉𝐕𝐌 𝐌𝐞𝐦𝐨𝐫𝐲 — 𝐓𝐡𝐞 𝐖𝐚𝐫𝐞𝐡𝐨𝐮𝐬𝐞 𝐒𝐭𝐨𝐫𝐚𝐠𝐞 𝐙𝐨𝐧𝐞𝐬 Once classes arrive, JVM memory organizes where everything lives: 📘 𝐌𝐞𝐭𝐡𝐨𝐝 𝐀𝐫𝐞𝐚 • Blueprint records: class structure, methods, static data • Shared reference catalog 📦 𝐇𝐞𝐚𝐩 • Where actual products (objects) are stored • Shared across all workers (threads) 🗂️ 𝐒𝐭𝐚𝐜𝐤 • Personal workbench per worker (thread) • Holds method calls & local variables 📮 𝐏𝐫𝐨𝐠𝐫𝐚𝐦 𝐂𝐨𝐮𝐧𝐭𝐞𝐫 (𝐏𝐂) • Tracks the current instruction each worker is handling ⚙️ 𝐍𝐚𝐭𝐢𝐯𝐞 𝐌𝐞𝐭𝐡𝐨𝐝 𝐒𝐭𝐚𝐜𝐤 • Manages external tools (native C/C++ operations) ✅ 𝐒𝐮𝐦𝐦𝐚𝐫𝐲 ✔️ ClassLoaders find and load Java classes ✔️ JVM Memory organizes and manages them ✔️ This entire process completes before execution begins #Java #JavaDailyUpdates #JavaDeveloper #JVM #ClassLoader #JavaMemory #JavaArchitecture #CoreJava #LearnJava #JavaConcepts #BackendDevelopment #SoftwareEngineering #JavaInterview #SystemDesign #ProgrammingConcepts #CodingTip #DevelopersOfLinkedIn #JavaCommunity #DailyLearning #DeveloperJourney #JavaCommunity #SoftwareDevelopment #SoftwareArchitecture #C2C #WebDevelopment #Developer #C2H #BackendEngineering #Microservices #JavaScript #Data #Deployment #FullStackDevelopment #TechTalk #SoftwareEngineering #Python #Java #AI #FullStack #Frontend #Backend #Cloud #Testing #OpentoWork #Jobs #Jobsearch #C2C #Data #Dataengineering #Automotive #Linkedin #Tips #DevOps #Remote #Hybrid #Senior #UST #Brooksource #ProwessSoft #KYYBAKYYBA Inc #Experis #SRSSRS Consulting Inc #TEKsystems #TheThe Judge Group #BeaconBeacon Hill #BayOneBayOne Solutions #RandstadRandstad USA #Insightglobal #JavaCommunity
To view or add a comment, sign in
-
-
🧠 𝗧𝗵𝗲 𝗛𝗶𝗱𝗱𝗲𝗻 𝗠𝗲𝗺𝗼𝗿𝘆 𝗦𝗶𝗻𝗸 (𝗣𝗮𝗿𝘁 𝟭𝟯.𝟱.𝟯): 𝗝𝗮𝘃𝗮 𝗛𝘁𝘁𝗽𝗖𝗹𝗶𝗲𝗻𝘁 - 𝗠𝗼𝗱𝗲𝗿𝗻 𝗦𝘁𝗮𝗰𝗸 𝗡𝗼𝗯𝗼𝗱𝘆 𝗨𝘀𝗲𝘀 Java 11 gave us HttpClient. HTTP/2 built-in. Connection pooling included. Async API. No OkHttp, Apache, or Netty dependency. Five years later, everyone still adds external HTTP libraries. Why? Spring Boot doesn't default to it. Teams don't know it exists. Legacy code stays legacy. But it's there. Java 21 virtual threads change blocking model. Time to reconsider built-in? --- 🔧 𝗪𝗵𝗮𝘁 𝗝𝗮𝘃𝗮 𝗛𝘁𝘁𝗽𝗖𝗹𝗶𝗲𝗻𝘁 𝗣𝗿𝗼𝘃𝗶𝗱𝗲𝘀 _HttpClient client = HttpClient.newBuilder() .version(Version.HTTP_2) // HTTP/2 default .connectTimeout(...) .build();_ 𝗕𝘂𝗶𝗹𝘁-𝗶𝗻: - HTTP/2 by default (fallback to HTTP/1.1) - Connection pooling (automatic) - Async and sync APIs (CompletableFuture) - No external dependencies --- 🔧 𝗪𝗵𝘆 𝗡𝗼𝗯𝗼𝗱𝘆 𝗨𝘀𝗲𝘀 𝗜𝘁 𝗦𝗽𝗿𝗶𝗻𝗴 𝗕𝗼𝗼𝘁 𝗱𝗲𝗳𝗮𝘂𝗹𝘁𝘀: RestTemplate (13.3), WebClient (13.4). Not Java HttpClient. 𝗟𝗲𝗴𝗮𝗰𝘆 𝗰𝗼𝗱𝗲 𝗨𝗻𝗳𝗮𝗺𝗶𝗹𝗶𝗮𝗿𝗶𝘁𝘆 𝗘𝗰𝗼𝘀𝘆𝘀𝘁𝗲𝗺: Fewer Stack Overflow answers, less community content. --- 🔧 𝗝𝗮𝘃𝗮 𝟮𝟭 𝗩𝗶𝗿𝘁𝘂𝗮𝗹 𝗧𝗵𝗿𝗲𝗮𝗱𝘀 𝗖𝗵𝗮𝗻𝗴𝗲 𝗧𝗵𝗲 𝗚𝗮𝗺𝗲 _HttpClient client = HttpClient.newHttpClient(); // Blocking call on virtual thread = no problem String response = client.send(request, BodyHandlers.ofString()).body();_ 𝗕𝗲𝗳𝗼𝗿𝗲 𝘃𝗶𝗿𝘁𝘂𝗮𝗹 𝘁𝗵𝗿𝗲𝗮𝗱𝘀: Blocking HTTP = platform thread per request. Doesn't scale (13.4). 𝗪𝗶𝘁𝗵 𝘃𝗶𝗿𝘁𝘂𝗮𝗹 𝘁𝗵𝗿𝗲𝗮𝗱𝘀: Blocking code performs like async. Simple blocking HttpClient calls scale to thousands of concurrent requests. 𝗧𝗿𝗮𝗱𝗲𝗼𝗳𝗳: WebClient reactive complexity vs HttpClient simplicity + virtual threads. Both scale. Different models. --- 🔧 𝗠𝗲𝗺𝗼𝗿𝘆 & 𝗖𝗼𝗻𝗳𝗶𝗴𝘂𝗿𝗮𝘁𝗶𝗼𝗻 𝗖𝗼𝗻𝗻𝗲𝗰𝘁𝗶𝗼𝗻 𝗽𝗼𝗼𝗹𝗶𝗻𝗴: Built-in, automatic. 𝗛𝗧𝗧𝗣/𝟮 𝘀𝘁𝗮𝘁𝗲: HPACK overhead same as any HTTP/2 client (13.5.2). 𝗗𝗲𝗽𝗲𝗻𝗱𝗲𝗻𝗰𝗶𝗲𝘀: Zero external. 𝗠𝗲𝗺𝗼𝗿𝘆 𝗳𝗼𝗼𝘁𝗽𝗿𝗶𝗻𝘁: fewer jars. --- ⚖️ 𝗧𝗿𝗮𝗱𝗲𝗼𝗳𝗳𝘀 𝗝𝗮𝘃𝗮 𝗛𝘁𝘁𝗽𝗖𝗹𝗶𝗲𝗻𝘁: ✓ HTTP/2 built-in, no dependencies, virtual thread ready ✗ Less Spring integration, smaller ecosystem, less familiar 𝗢𝗸𝗛𝘁𝘁𝗽/𝗔𝗽𝗮𝗰𝗵𝗲: ✓ Mature, large ecosystem, Spring integrated ✗ External dependencies, more complex configuration 𝗪𝗲𝗯𝗖𝗹𝗶𝗲𝗻𝘁: ✓ Reactive, Spring native, high concurrency ✗ Reactor complexity, learning curve (13.4) --- 𝗧𝗵𝗲 𝗕𝗼𝘁𝘁𝗼𝗺 𝗟𝗶𝗻𝗲 Built-in HTTP finally viable. Reconsider dependency bloat. #Java #HttpClient #Java11 #Java21 #VirtualThreads #HTTP2 #Performance #Memory #NoDependencies #JavaPerformance #BackendDevelopment #ProjectLoom #ModernJava #CloudComputing #EnterpriseJava #DevOps #Microservices #MemoryOptimization #SoftwareEngineering #CloudNative #ProductionReady #JavaDevelopment #Async #NonBlocking #HighScale
To view or add a comment, sign in
-
💡 SOLID Principles in Java When building scalable and maintainable software, writing code that just works is not enough. We need code that is clean, flexible, and easy to extend. That’s where SOLID principles come in. 🔹 1. Single Responsibility Principle (SRP) A class should have only one reason to change. ❌ Bad Example: java class OrderService { void createOrder() { } void saveToDB() { } void log() { } } ✅ Good Example: java class OrderService { void createOrder() { } } class OrderRepository { void save() { } } class LoggerService { void log() { } } 🔹 2. Open/Closed Principle (OCP) Open for extension, closed for modification. ❌ Bad Example: java class PaymentService { void pay(String type) { if(type.equals("UPI")) { } else if(type.equals("CARD")) { } } } ✅ Good Example: java interface Payment { void pay(); } class UpiPayment implements Payment { public void pay() { } } class CardPayment implements Payment { public void pay() { } } 🔹3. Liskov Substitution Principle (LSP) Subclasses should replace parent classes without breaking behavior. ❌ Bad Example: java class Bird { void fly() { } } class Ostrich extends Bird { void fly() { throw new RuntimeException("Can't fly"); } } ✅ Good Example: java class Bird { } class FlyingBird extends Bird { void fly() { } } class Ostrich extends Bird { } class Sparrow extends FlyingBird { void fly() { } } 🔹 4. Interface Segregation Principle (ISP) Clients shouldn’t depend on methods they don’t use. ❌ Bad Example: java interface Worker { void work(); void eat(); } class Robot implements Worker { public void work() { } public void eat() { } // not needed } ✅ Good Example: java interface Workable { void work(); } interface Eatable { void eat(); } class Robot implements Workable { public void work() { } } 🔹 5. Dependency Inversion Principle (DIP) High-level modules should not depend on low-level modules. Both should depend on abstractions. ❌ Bad Example: java class PaymentService { void pay() { } } class OrderService { private PaymentService paymentService = new PaymentService(); } ✅ Good Example (Spring Boot): java interface PaymentService { void pay(); } @Service class UpiPaymentService implements PaymentService { public void pay() { } } @Service class OrderService { private final PaymentService paymentService; @Autowired public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } } 🚀 Final Thought: SOLID is not just theory — it’s the foundation of scalable systems and clean architecture. 👉 Write code that not only works today, but is easy to extend tomorrow. #SOLID #Java #SpringBoot #CleanCode #SoftwareEngineering #BackendDevelopment #SystemDesign
To view or add a comment, sign in
-
-
𝗗𝗔𝗬 𝟯 – 𝗦𝘁𝗿𝘂𝗰𝘁𝘂𝗿𝗲 𝗼𝗳 𝗮 𝗝𝗮𝘃𝗮 𝗣𝗿𝗼𝗴𝗿𝗮𝗺 + 𝗝𝗮𝘃𝗮 𝗧𝗼𝗸𝗲𝗻𝘀 𝗜𝗻 𝘁𝗵𝗲 𝗹𝗮𝘀𝘁 𝘁𝘄𝗼 𝗽𝗼𝘀𝘁𝘀 𝘄𝗲 𝘂𝗻𝗱𝗲𝗿𝘀𝘁𝗼𝗼𝗱: • Why Java is Platform Independent • How JDK, JRE, and JVM work together to run a Java program Now it's time to move from 𝘁𝗵𝗲𝗼𝗿𝘆 → 𝗮𝗰𝘁𝘂𝗮𝗹 𝗰𝗼𝗱𝗲. 𝗟𝗲𝘁’𝘀 𝘄𝗿𝗶𝘁𝗲 𝗮 𝘀𝗶𝗺𝗽𝗹𝗲 𝗝𝗮𝘃𝗮 𝗽𝗿𝗼𝗴𝗿𝗮𝗺. ``` 𝚙𝚞𝚋𝚕𝚒𝚌 𝚌𝚕𝚊𝚜𝚜 𝙷𝚎𝚕𝚕𝚘𝚆𝚘𝚛𝚕𝚍 { 𝚙𝚞𝚋𝚕𝚒𝚌 𝚜𝚝𝚊𝚝𝚒𝚌 𝚟𝚘𝚒𝚍 𝚖𝚊𝚒𝚗(𝚂𝚝𝚛𝚒𝚗𝚐[] 𝚊𝚛𝚐𝚜) { 𝚂𝚢𝚜𝚝𝚎𝚖.𝚘𝚞𝚝.𝚙𝚛𝚒𝚗𝚝𝚕𝚗("𝙷𝚎𝚕𝚕𝚘 𝚆𝚘𝚛𝚕𝚍"); } } ``` At first glance this may look confusing. But if we break it down, the structure becomes very simple. 𝗦𝘁𝗿𝘂𝗰𝘁𝘂𝗿𝗲 𝗼𝗳 𝗮 𝗝𝗮𝘃𝗮 𝗣𝗿𝗼𝗴𝗿𝗮𝗺 Every Java program generally contains: 1️⃣ 𝗖𝗹𝗮𝘀𝘀 𝗗𝗲𝗰𝗹𝗮𝗿𝗮𝘁𝗶𝗼𝗻 𝚙𝚞𝚋𝚕𝚒𝚌 𝚌𝚕𝚊𝚜𝚜 𝙷𝚎𝚕𝚕𝚘𝚆𝚘𝚛𝚕𝚍 In Java, everything starts with a class. The filename must match the class name. Example: 𝙷𝚎𝚕𝚕𝚘𝚆𝚘𝚛𝚕𝚍.𝚓𝚊𝚟𝚊 2️⃣ 𝗠𝗮𝗶𝗻 𝗠𝗲𝘁𝗵𝗼𝗱 𝚙𝚞𝚋𝚕𝚒𝚌 𝚜𝚝𝚊𝚝𝚒𝚌 𝚟𝚘𝚒𝚍 𝚖𝚊𝚒𝚗(𝚂𝚝𝚛𝚒𝚗𝚐[] 𝚊𝚛𝚐𝚜) This is the entry point of every Java program. When we run a program, the JVM starts execution from the 𝗺𝗮𝗶𝗻() 𝗺𝗲𝘁𝗵𝗼𝗱. 3️⃣ 𝗦𝘁𝗮𝘁𝗲𝗺𝗲𝗻𝘁𝘀 𝚂𝚢𝚜𝚝𝚎𝚖.𝚘𝚞𝚝.𝚙𝚛𝚒𝚗𝚝𝚕𝚗("𝙷𝚎𝚕𝚕𝚘 𝚆𝚘𝚛𝚕𝚍"); This statement simply prints output on the console. 𝗡𝗼𝘄 𝗹𝗲𝘁’𝘀 𝘂𝗻𝗱𝗲𝗿𝘀𝘁𝗮𝗻𝗱 𝘀𝗼𝗺𝗲𝘁𝗵𝗶𝗻𝗴 𝘃𝗲𝗿𝘆 𝗶𝗺𝗽𝗼𝗿𝘁𝗮𝗻𝘁 𝗶𝗻 𝗝𝗮𝘃𝗮. 𝗝𝗮𝘃𝗮 𝗧𝗼𝗸𝗲𝗻𝘀 Tokens are the smallest building blocks of a Java program. Java programs are basically made up of tokens. 𝗧𝗵𝗲𝗿𝗲 𝗮𝗿𝗲 𝗺𝗮𝗶𝗻𝗹𝘆 𝟱 𝘁𝘆𝗽𝗲𝘀: • 𝗞𝗲𝘆𝘄𝗼𝗿𝗱𝘀 → public, class, static, void • 𝗜𝗱𝗲𝗻𝘁𝗶𝗳𝗶𝗲𝗿𝘀 → names of variables, classes, methods • 𝗟𝗶𝘁𝗲𝗿𝗮𝗹𝘀 → actual values (10, "Hello", true) • 𝗦𝗲𝗽𝗮𝗿𝗮𝘁𝗼𝗿𝘀 → { } ( ) [ ] ; , • 𝗢𝗽𝗲𝗿𝗮𝘁𝗼𝗿𝘀 → + - * / = == Example identifier rules: ✔ Cannot start with a number ✔ Cannot use Java keywords ✔ No spaces allowed ✔ Can use letters, numbers, _ and $ Once you understand structure + tokens, reading Java code becomes much easier. If you look at the Java program again, you’ll now notice: It is simply a combination of tokens working together. Once you understand tokens and structure, reading Java code becomes much easier. 𝗧𝗼𝗺𝗼𝗿𝗿𝗼𝘄 (𝗗𝗮𝘆 𝟰) 𝗪𝗲’𝗹𝗹 𝗴𝗼 𝗱𝗲𝗲𝗽𝗲𝗿 𝗶𝗻𝘁𝗼 𝗼𝗻𝗲 𝗼𝗳 𝘁𝗵𝗲 𝗺𝗼𝘀𝘁 𝗶𝗺𝗽𝗼𝗿𝘁𝗮𝗻𝘁 𝘁𝗼𝗽𝗶𝗰𝘀 𝗶𝗻 𝗝𝗮𝘃𝗮: • Data Types • Variables • Primitive vs Non-Primitive types • Memory basics behind variables Because before writing real programs, understanding how Java stores data is critical. 𝗦𝗲𝗲 𝘆𝗼𝘂 𝗶𝗻 𝗗𝗮𝘆 𝟰. #Java #BackendDevelopment #Programming #LearnInPublic #Day3
To view or add a comment, sign in
-
🧠 It's Monday and is time for a new java post. Now we go back to basics and who it was handled through the versions. Let's consider the method: public static String decorate(String value) { return "prefix$"+value+"$suffix"; } From Java 1 to 4 the concatenation would be equivalent to new StringBuffer("prefix$").append(value).append($suffix).toString(). This was would create a synchronized object, which inside would allocate an array that if need be would double its size every time you need extra space. Java 5-8 would play the same game but StringBuffer was replace with the non-synchronized StringBuilder. From Java 9 though you don't have a direct Java equivalent, or not straight forward at least as they switch to an implementation based on invoke dynamic. Let's see what javap produces: 0: aload_0 1: invokedynamic #16, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 6: areturn .... BootstrapMethods: 0: #29 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite; Method arguments: #30 prefix$\u0001$suffix In laymen terms, the first time a concatenation would happen, the code would call StringConcatFactory::makeConcatWithConstants to create a object with a single String parameter and returning the another String. This method would replace \u0001 in the prefix$\u0001$suffix recipe however it would seem to be the best. The object than is cached and the actual method is called. Every time the same object will be reused. Did you as Java developers know about this latest process?
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