Java
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented Java
-
Section 4: Collections Framework
-
Section 5: Exception Handling
-
Section 6: Generics
-
Section 7: Functional Java
-
Section 8: Concurrency
-
Section 9: I/O and NIO
-
Section 10: JVM Internals
-
Section 11: Modern Java Features
-
Section 12: Build Tools and Project Structure
-
Section 13: Testing
-
Section 14: Databases and Persistence
-
Section 15: Networking
-
Section 16: Design and Best Practices
-
Section 17: Reflection and Annotations
-
Section 18: Logging and Diagnostics
-
Section 19: Date, Time, and Internationalization
-
Section 20: Java Platform Module System
-
Section 21: Security in Java
-
Section 22: Advanced Collections and Data Structures
-
Section 23: More Concurrency Patterns
-
Section 24: Compression, Files, and System Integration
-
Section 25: GUI Programming
-
Section 26: Practical Projects
-
Section 27: Data Structures and Algorithms
-
Section 28: Interview and Algorithm Practice
-
Section 29: JSON and Data Interchange
-
Section 30: More Concurrency Utilities
-
Section 31: More Collections and Streams Practice
-
Section 32: More File and System Programming
-
Section 33: Standard Library Deep Dive
-
Section 34: More Practice and Drills
-
Section 35: More Testing and Quality
-
Section 36: More Design Patterns and Architecture
-
Section 37: Career and Ecosystem
-
Section 38: More OOP and Architecture Practice
-
Section 39: More Enterprise Concepts
-
Section 40: Advanced JavaFX
-
Section 41: More Interview Practice
61: Generic Classes and Methods
Why can't I just use Object to handle any data type?
I get this question a lot. Technically, you can. Since every class in Java inherits from Object, you could write a class that stores an Object and it would "work." The problem is that you're essentially lying to the compiler. You're saying, "I'm storing something," but you aren't saying what.
When you pull that object back out, you have to cast it. If you accidentally put a String in there but try to cast it to an Integer, the compiler won't stop you—but your app will crash with a ClassCastException the moment that line runs. Generics move that mistake from runtime (where your users see it) to compile-time (where you see it). I'd much rather have a red squiggly line in my IDE than a crash report in my inbox.
How do I actually define a generic class?
Think of a generic class as a template. Instead of picking a specific type now, you're using a placeholder. By convention, we use T for "Type," but you could call it Whatever if you really wanted to.
Let's say we're building a system that wraps API responses. We want to return a status code and some data, but that data could be a User, a Product, or a List of orders. Here is how I'd handle that:
public class Response<T> {
private T data;
private int statusCode;
public Response(T data, int statusCode) {
this.data = data;
this.statusCode = statusCode;
}
public T getData() {
return data;
}
public int getStatusCode() {
return statusCode;
}
}
Now, when you instantiate this, you tell Java exactly what T should be for that specific instance:
// This response specifically holds a String
Response<String> welcomeMsg = new Response<String>("Hello!", 200);
// This one holds an Integer
Response<Integer> errorCode = new Response<Integer>(404, 404);
// No casting needed!
String message = welcomeMsg.getData();
Do I have to make the whole class generic if I only need one flexible method?
Nope. You can define "generic methods." This is incredibly useful for utility classes where most of the logic is static, but a couple of methods need to handle different types. To do this, you put the type parameter <T> before the return type of the method.
Here's a quick example of a utility method that swaps two elements in an array, regardless of whether it's an array of Strings, Integers, or custom objects:
public class ArrayUtils {
public static <T> void swap(T[] array, int index1, int index2) {
T temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
}
Notice that ArrayUtils itself isn't generic—it doesn't have <T> next to the class name. Only the swap method is. This keeps your class clean and only introduces flexibility exactly where you need it.
📋 Practical Task
Implement a Generic Data Vault
You need to create a simple "Vault" class that stores a single piece of sensitive data. This vault should be generic so it can store a String (like a password), an Integer (like a PIN), or even a custom Key object.
- Create a generic class named
DataVault<T>. - Add a private field of type
Tto hold the secret. - Create a constructor that initializes this secret.
- Implement a method called
retrieveSecret()that returns the secret. - In a
mainmethod, instantiate two different vaults: one for aStringpassword and one for anIntegerPIN. Print both secrets to the console to verify that the types are preserved without manual casting.
There are no comments for now.