Java Generics Tutorial

Jakob Jenkov
Last update: 2024-08-03

Java Generics enable us to gain type safety in situations where classes and methods that are designed to be able to work with any type would otherwise be designed to work with Object instances. For instance, without Java Generics the Java List, Java Set, Java Map etc. interfaces would all be working on Object instances. With Java Generics you can create List, Set or Map instances that work on specific types, e.g. a List of Strings, rather than a List of Objects, so you achieve a higher type safety in your code.

Java Generics add type parameters to classes, interfaces, methods and variables that decide to use them. To be able to use a type parameter with a class, interface, method or variable the type you are trying to add the type parameter to, must be designed to allow generic type parameters.

Many of Java's built-in utility classes and interfaces are designed to allow generic type parameters. This Java Generics tutorial shows examples of how to use generic type parameters with some of these classes. Once you have seen a few examples, you can figure out how to use generic type parameters in general.

You can also design your own classes, interfaces and methods to use usable with Java Generics - meaning enabling them to take type parameters. This Java Generics tutorial also shows how to do that.

Java Generics Tutorial Video

Java Generics Tutorial Video
Java Generics Tutorial Video

Java Generics Example

Java Generics and type parameters sounds a bit abstract, so let us look at a simple Java Generics example.

The List interface represents a list of Object instances. This means that we could put any object into a List. Here is an example:

List list = new ArrayList();

list.add(new Integer(2));
list.add("a String");

Because any object could be added, you would also have to cast any objects obtained from these objects. For instance:

Integer integer = (Integer) list.get(0);

String  string  = (String)  list.get(1);

Very often you only use a single type with a collection. For instance, you only keep String's or something else in the collection, and not mixed types like I did in the example above.

With the Java Generics features you can set the type of the collection to limit what kind of objects can be inserted into the collection. Additionally, you don't have to cast the values you obtain from the collection. Here is an example using Java's Generic's features:

List<String> strings = new ArrayList<String>();

strings.add("a String");

String aString = strings.get(0);

Nice, right?

Java Generics Type Inference

The Java generics features were updated in Java 7. From Java 7 the Java compiler can infer the type of the collection instantiated from the variable the collection is assigned to. Here is a Java 7 generics example:

List<String> strings = new ArrayList<>();

Notice how the generic type of the ArrayList has been left out. Instead is only the <> written. This is also sometimes referred to as the diamond operator. When you just write a diamond operator as generic type, the Java compiler will assume that the class instantiated is to have the same type as the variable it is assigned to. In the example above, that means String because the List variable has String set as its type.

Java Generics for Loop

Java 5 also got a new for-loop (also referred to as "for-each") which works well with generified collections. Here is an example:

List<String> strings = new ArrayList<String>();

//... add String instances to the strings list...

for(String aString : strings){
  System.out.println(aString);
}

This for-each loop iterates through all String instances kept in the strings list. For each iteration, the next String instance is assigned to the aString variable. This for-loop is shorter than original while-loop where you would iterate the collections Iterator and call Iterator.next() to obtain the next instance.

The generic for loop (AKA "for each loop") is described in more detail in the tutorial about the Java generic for loop .

Java Generics for Collections

Java generics are quite often used with the data structures in the Java Collections API. For instance, you can use Java generics with a List, Set and Map, as explained in these articles:

Java Generics for Other Types than Collections

It is of course possible to use Generics for other classes than the Java collections.

You can use Java generics in your own classes too. Using Java generics in your own classes is described in more detail in these tutorials:

You can also implement the Java Iterable interface using Java generics. Doing so is explained here:

Java Generics Wildcards

The Java generics wildcards enable you to specify not just a specific generic type for a class or collection, but that the required type could also be either a superclass or subclass of the given type. Java generic wildcards are explained in more detail here:

Additional Java Generics Tutorials

To understand how Java Generics work all around, you will need to study the following topics:

Each of those topics are covered in their own tutorials. The rest of this page will introduce Java Generics to you, so it can be useful to read the rest of this introduction before you continue to any of the above links.

Jakob Jenkov

Featured Videos

Java ConcurrentMap + ConcurrentHashMap

Java Generics

Java ForkJoinPool

P2P Networks Introduction

















Close TOC
All Tutorial Trails
All Trails
Table of contents (TOC) for this tutorial trail
Trail TOC
Table of contents (TOC) for this tutorial
Page TOC
Previous tutorial in this tutorial trail
Previous
Next tutorial in this tutorial trail
Next