Skip to Content
Course content

61: Generic Classes and Methods

Click on the "Edit" button in the top corner of the screen to edit your slide content.

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 T to hold the secret.
  • Create a constructor that initializes this secret.
  • Implement a method called retrieveSecret() that returns the secret.
  • In a main method, instantiate two different vaults: one for a String password and one for an Integer PIN. Print both secrets to the console to verify that the types are preserved without manual casting.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.