☕ Java Generics – Bounded Type Parameters Explained Generics in Java provide type safety and flexibility. But sometimes, we need to restrict the type of objects that can be passed to a generic method or class. That’s where Bounded Type Parameters come into play. 🔹 What Are Bounded Type Parameters? There may be situations where a method should only accept specific types. For example: A method that works with numbers should only accept instances of Number or its subclasses. To restrict types, we use: <T extends SomeClass> The extends keyword specifies the upper bound of the type parameter. 👉 In generics, extends means: “extends” for classes “implements” for interfaces 🔹 Example – Generic Method to Find Maximum of Three Values public static <T extends Comparable<T>> T maximum(T x, T y, T z) { T max = x; if (y.compareTo(max) > 0) { max = y; } if (z.compareTo(max) > 0) { max = z; } return max; } 📌 Explanation: ✔ <T extends Comparable<T>> ensures only comparable types are allowed ✔ Uses compareTo() method ✔ Returns the largest of three objects 🔹 Sample Output Max of 3, 4 and 5 is 5 Max of 6.6, 8.8 and 7.7 is 8.8 Max of pear, apple and orange is pear This works for: ✔ Integers ✔ Doubles ✔ Strings Because all of them implement the Comparable interface. 💡 Bounded type parameters improve type safety, enforce constraints at compile time, and make generic methods more powerful and reliable. Mastering Generics is essential for writing reusable and scalable Java applications. #Java #Generics #BoundedTypeParameters #JavaProgramming #OOP #FullStackJava #Developers #AshokIT
Java Bounded Type Parameters Explained
More Relevant Posts
-
❗ Java Bug: Why final List or final Map Is Not Immutable in Java Recently, I ran into immunity issue in Java, which I've never paid attention before. It’s a common misconception that marking a field final automatically makes it “safe” or “immutable.” Unfortunately, this is not true when the field holds a mutable object such as a List or Map. Let’s look at this Java class: @Getter @Builder public class Plan { private final List<String> toDoList; } At first glance, this looks immutable: the field is final, and there is no setter. But watch what happens: List<String> initialToDoList = new ArrayList<>(Arrays.asList("Buy groceries", "Read a book", "Exercise")); var plan = Plan.builder().toDoList(initialToDoList).build(); List<String> firstList = plan.getToDoList(); firstList.size()==3; firstList .add("Learn Java"); //No Exception Obtain list again AFTER adding the item: List<String> secondList = plan.getToDoList(); Now firstList.size()==4 and secondList.size()==4 firstList contains the newly added item 'Learn Java' secondList contains the newly added item 'Learn Java' ❇️ Conclusion: Summary object looks immutable from the outside, but its internal state can be changed at any time. That’s not immutability—that’s an illusion of immutability. I feel it's a Java Bug. If it's final, why not just make it immutable no matter if it's a collection or not 😂. #Java
To view or add a comment, sign in
-
☕ Java Generics – Upper Bounded Wildcards Explained In Java Generics, the question mark (?) represents a wildcard, meaning an unknown type. Sometimes, we need to restrict the type of objects that can be passed to a method — especially when working with numbers or specific class hierarchies. That’s where Upper Bounded Wildcards come into play. 🔹 What is an Upper Bounded Wildcard? To restrict a wildcard to a specific type or its subclasses, we use: <? extends ClassName> This means: 👉 Accept ClassName or any of its subclasses. For example, if a method should only work with numeric types, we restrict it to Number and its subclasses like Integer, Double, etc. As explained in the document (Page 1), the syntax uses ? followed by the extends keyword to define the upper bound. 🔹 Practical Example From the example shown (Page 2), a method calculates the sum of elements in a list: public static double sum(List<? extends Number> numberlist) { double sum = 0.0; for (Number n : numberlist) sum += n.doubleValue(); return sum; } 📌 Why ? extends Number? ✔ Ensures only numeric types are allowed ✔ Accepts List<Integer> ✔ Accepts List<Double> ✔ Maintains type safety 🔹 Usage in Main Method List<Integer> integerList = Arrays.asList(1, 2, 3); System.out.println("sum = " + sum(integerList)); List<Double> doubleList = Arrays.asList(1.2, 2.3, 3.5); System.out.println("sum = " + sum(doubleList)); 🔹 Output (Page 3) sum = 6.0 sum = 7.0 This demonstrates how the same method works seamlessly with different numeric types. 💡 Upper bounded wildcards improve flexibility while maintaining compile-time type safety. They are essential for writing reusable and robust generic methods in Java. #Java #Generics #UpperBoundedWildcards #JavaProgramming #OOP #FullStackJava #Developers #AshokIT
To view or add a comment, sign in
-
❗ Even Java record Don’t Make Maps Immutable It’s a common misconception that Java record automatically provides immutability for the fields. Actually, Java record doesn't make mutable objects (like Map, List, Set) immutable. 💡 Example: A Record with a Map @Builder public record Summary(Map<String, Address> addressMap) { } Then try this: var summary = Summary.builder() .addressMap(existingMap) .build(); var map = summary.addressMap(); map.put("newAddress", Address.builder().street("main").build()); // ❗ This works! ✔ No exception is thrown addressMap() simply returns the internal Map reference. Since Map is mutable, external code can still change the record’s internal state. This means: Records prevent reassignment, but they do not prevent mutation of contained objects. 🔒 How to Make the Map Truly Immutable To ensure callers can’t mutate your internal Map, you must explicitly defensively copy it. You can do this using the compact constructor as shown in the example, which runs after the canonical constructor is generated: @Builder public record Summary(Map<String, Address> addressMap) { public Summary { // Defensive copy to ensure immutability addressMap = (addressMap == null) ? Map.of() : Map.copyOf(addressMap); } } ✔ Why this works Map.copyOf(...) creates a new, unmodifiable map. Any attempt to modify the returned map will throw UnsupportedOperationException. Your record no longer exposes internal mutable state. var summary = Summary.builder() .addressMap(existingMap) .build(); summary.addressMap().put("x", someAddress); // → UnsupportedOperationException 📝 Summary Records do not make mutable fields immutable. final only protects references, not the objects they reference. If a record contains a Map, List, or Set, callers can mutate it unless you: Wrap it with Map.copyOf / List.copyOf / Set.copyOf The compact constructor is the cleanest way to enforce immutability in records. #Java #MyWorkExperience
To view or add a comment, sign in
-
Most Java developers get confused by this exception. Let me explain why. You run this code: System.out.println("12345".charAt(6)); And the stack trace says StringIndexOutOfBoundsException. But wait... shouldn't it be IndexOutOfBoundsException? 🤔 Here's the thing: it IS an IndexOutOfBoundsException. Java's exception hierarchy uses inheritance to give you MORE specific information, not different information. The hierarchy looks like this: RuntimeException └── IndexOutOfBoundsException ├── StringIndexOutOfBoundsException └── ArrayIndexOutOfBoundsException This is polymorphism applied to exceptions 💡 → charAt() throws StringIndexOutOfBoundsException because the problem happened in a String → array[10] throws ArrayIndexOutOfBoundsException because the problem happened in an array → list.get(99) throws IndexOutOfBoundsException because the problem happened in a collection → A catch(IndexOutOfBoundsException e) block catches ALL of them Why does this matter? When you write catch blocks, you can choose your level of specificity. Catching the parent handles everything. Catching the child gives you precise control over what you handle and what you propagate. This is the same design principle behind Java's entire exception framework: specificity through inheritance. Understanding this hierarchy is what separates a developer who reads stack traces from one who truly understands them. ⚡ What other Java exceptions have tripped you up? Drop them in the comments 👇 📊 Oracle Java SE 17 Docs - IndexOutOfBoundsException API (2025) https://lnkd.in/eN_5XAp4 📊 Baeldung - Java ArrayIndexOutOfBoundsException (2025) https://lnkd.in/evZcjMHs 📊 Rollbar - How to Handle StringIndexOutOfBoundsException in Java (2022) https://lnkd.in/erHwcX4T #Java #SoftwareEngineering #Backend #ExceptionHandling #Programming #OOP #JavaDeveloper #CleanCode
To view or add a comment, sign in
-
Core Java (Deep Concepts): 1️⃣ What happens internally in HashMap when two keys generate the same hash? Collision occurs. HashMap stores entries in buckets indexed by hash(key). Before Java 8: linked list. Java 8+: red-black tree if list grows beyond 8. equals() is checked for key match. 2️⃣ How does ConcurrentHashMap achieve thread safety? Fine-grained locking or CAS for writes. Reads mostly lock-free. Allows concurrent read/write without locking the entire map. 3️⃣ Difference between Synchronized Collections and Concurrent Collections: Synchronized: coarse-grained, single-thread access, e.g., Collections.synchronizedList. Concurrent: fine-grained, multiple threads can access, e.g., ConcurrentHashMap. 4️⃣ Volatile vs Synchronization: Volatile: ensures visibility only, no mutual exclusion. Synchronization: ensures visibility + mutual exclusion. 5️⃣ Explain Java Memory Model (JMM): Defines thread interactions via memory. Key concepts: main memory vs CPU cache, happens-before relationship, visibility with volatile, atomicity with synchronized. 6️⃣ Difference between Future and CompletableFuture: Future: waits for the result, limited. CompletableFuture: async, chaining, handles exceptions, supports multiple futures. 7️⃣ Parallel Streams: Executes operations in parallel via ForkJoinPool. Avoid when shared mutable state exists, small datasets, or ordering matters. 8️⃣ ClassLoader in Java: Loads class bytecode into JVM. Types: Bootstrap, Extension, System/Application, Custom. 9️⃣ Sealed Classes Allows developers to restrict which classes can extend or implement a class or interface, improving domain modeling and security. 🔟 What is a record in Java? A record is a special type of class used to model immutable data objects with very little boilerplate code. It automatically generates: constructor getters equals() hashCode() toString()
To view or add a comment, sign in
-
Core Java Fundamentals :Key Traits of Metaspace Permanent Generation in Java PermGen (Permanent Generation) was a memory area in the Java Virtual Machine (JVM) used before Java 8 to store class metadata, interned strings, and static variables. It was part of the JVM heap space and had a fixed size, making it difficult to manage memory efficiently. Fixed and Hard-to-Tune Size in PermGen PermGen had a fixed maximum size, which was often too small for applications with many classes. Correct Tuning was Tricky Even though it was configurable using -XX:MaxPermSize, tuning it correctly was difficult. PermGen was not dynamically expanding Unlike Metaspace, on the other hand, dynamically expands using native memory, eliminating manual tuning issues. OutOfMemoryError If class metadata exceeded 256MB, the application would crash with OutOfMemoryError: PermGen space. Key Features of Metaspace Stores Class Metadata It holds information about classes, methods, and their runtime representations (like method bytecode and field details). Unlike PermGen, it does not store Java objects (which reside in the heap). Uses Native Memory Unlike PermGen, which had a fixed maximum size, Metaspace dynamically expands using native memory(outside the heap), reducing Out of memory errors. Automatic Growth & GC Handling The JVM automatically manages Metaspace size based on the application’s needs. Class metadata is garbage collected when classes are no longer needed (such as when an application uses dynamic class loading). Configurable Maximum Size -XX:MaxMetaspaceSize=256m // Limits Metaspace to 256MB -XX:MetaspaceSize=128m // Initial size before expanding ☕ If this helped you — support my work: 👉 Buy Me a Coffee -https://lnkd.in/ebXVUJn2 #JVMInternals #JavaPerformance #MemoryManagement #SpringBoot #Microservices #SystemDesign
To view or add a comment, sign in
-
-
Day 6: CONDITIONAL STATEMENTSIN JAVA Decision making instructions in Java: •If else statement •else if •Switch statement # If else statement The syntax of an if else statement in C looks like that of C++ and JavaScript. Java has a similar syntax too. It looks like: Syntax: if (condition-to-be-checked) { statements if condition true; } else { statements if condition false; } Example: int age = 14; if (age > 18) { sout("Yes you can drive"); } else { sout("You cannot drive"); } # Else if clause Instead of using multiple if statements, we can also use else if along with if, thus forming an if else if ladder. Syntax: if (condition) { // statements; } else if (condition) { // statements; } else { // statement; } # Switch case control instruction Switch-case is used when we have to make a choice between number of alternatives for a given variable. Syntax: switch (Var) { case C1: // code; break; case C2: // code break; case C3: // code break; default: // code; }
To view or add a comment, sign in
-
-
💡 Java Tip: Why You Should Be Careful with "Optional" "Optional" in Java was introduced to avoid "NullPointerException"… but many developers still misuse it. Here are a few things to keep in mind: 👉 1. Don’t use "Optional" as a field in entities It was designed for return types, not for class fields. 👉 2. Avoid "isPresent()" + "get()" This defeats the purpose of "Optional". Instead, use: - "orElse()" - "orElseGet()" - "ifPresent()" 👉 3. Don’t overuse it Sometimes a simple null check is more readable than wrapping everything in "Optional". 👉 4. Prefer functional style Example: "userOptional.map(User::getName).orElse("Unknown")" --- 🔍 Quick thought: "Optional" is not a replacement for null — it's a tool to write cleaner, safer code when used correctly. --- What’s one mistake you’ve seen (or made 😄) while using "Optional"? #Java #CleanCode #BackendDevelopment #JavaTips #Developers
To view or add a comment, sign in
-
🚀 Java Series – Day 3 📌 Operators in Java 🔹 What is it? Operators are special symbols in Java used to perform operations on variables and values. Java mainly provides different types of operators such as: • Arithmetic Operators – + - * / % • Relational Operators – == != > < >= <= • Logical Operators – && || ! • Assignment Operators – = += -= *= /= • Increment / Decrement Operators – ++ -- 🔹 Why do we use it? Operators help programs perform calculations and make decisions. For example: In an e-commerce application, operators can be used to calculate the total price, check discount conditions, or verify whether a user is eligible for an offer. 🔹 Example: public class Main { public static void main(String[] args) { int a = 10; int b = 5; // Arithmetic operator System.out.println(a + b); // Relational operator System.out.println(a > b); // Logical operator System.out.println(a > 5 && b < 10); } } 💡 Key Takeaway: Operators are the building blocks of logic in Java programs and are essential for calculations and decision-making. What do you think about this? 👇 #Java #CoreJava #JavaDeveloper #Programming #BackendDevelopment
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