Java Generics

Towni Eyan
Aug 24, 2017 · 4 min read

Abstraction doesn’t end with classes and methods. You can even have abstract data types! Generics is what makes it possible. In other words, with generics you can provide data types to classes and methods like this:

Here, we are passing the data type “String” to the class “ArrayList.” Essentially this means, “Hey ArrayList! I want to store Strings. Thank you.” In place of “String,” you can have any non-primitive data type you want. Generics do not work with primitive data types.

Now let’s look at this more closely.

By now, you should understand that classes usually hold data and houses methods for dealing with those data.

When you’ve created a class in Java, the next question you may have in your mind is, “Wait, what type of data am I going to deal with?”

Sometimes, you have the answer is too obvious. For a class like, “Rectangle” with data like, “width” and “height,” it’s obvious that you’re going to use something specific like an int here.

But you want the width and height to have non-discrete values too! In other words, you may want to let the Rectangle be instantiated with width and heights as double/float along besides int. You want the data type to be abstract, only to be specified during instantiation. Generic types come to scene to make data type abstraction possible. Here’s how:

In the class’s header, “<T>” means “Hey, just pass in a data type, I’ll call it ‘T’”. Whenever you want to use this abstract type, just use the name. In this case, we call it “T”.

You also could have called the generic type something else other than“T”:

You get the idea, you can call it anything you like but it’s best practise to capitalize it. You just defined your own data type, congrats! I mean, thanks to generics :P

So here’s how you specify data types for width and height of the Rectangle:

We’ve created 3 Rectangles, rect, rect2 and rect3 with widths and heights as Integer, Float and Double respectively.

Multiple generic types

Next time your boss comes up to you and tells you to define Rectangle so the data type of width and height can each be specified individually. I mean, you can have one generic data type for width and another for height. Here’s how you can do it and not get fired:

Providing bounds

But here comes another problem. What if someone provides String for a type? It wouldn’t make any sense to allow someone to do that. That’s when you’ve to limit the range of types that can be specified.

You can accomplish this by making sure T1 and T2 are childs of Number. In other words, you’re only going to accept data types which holds numbers. It’s because Integer, Float, Double, etc are all children of Number. Look it up in the documentation of Java for more information.

It basically means that T1 and T2 should extend Number. Doesn’t mean any actual inheritance is taking place. It’s a common misconception.

For sake of simplicity, let’s keep only one generic type. Here’s how the class may look like with methods:

Wildcard Generics

Now let’s say we wanna (just for fun) create a class called “ListCounter” which takes an ArrayList and counts the number of elements inside it. Here’s how it’s done:

The “?” is a wildcard generic and basically means, “Hey, I’m cool with any ArrayList which contains anything.“ It’s a way of having abstraction in multiple levels.

For some weird reason, maybe you want to accept ArrayLists which only contains numbers. This is how you do it:

It essentially means, “I am cool with anything which extends Number.” Instead of “extends,” you could use “super” to mean that the generic type must be the parent class of Number.

)
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade