Skip to content
On this page

Writing generics

Writing generic classes is more complex than ordinary classes. Generally speaking, generic classes are generally used in collection classes, such as ArrayList<T> . We rarely need to write generic classes.

If we really need to write a generic class, how should we write it?

You can follow the steps below to write a generic class.

First, write a class according to a certain type, such as String :

java
public class Pair {
    private String first;
    private String last;
    public Pair(String first, String last) {
        this.first = first;
        this.last = last;
    }
    public String getFirst() {
        return first;
    }
    public String getLast() {
        return last;
    }
}

Then, mark all the specific types, in this case String , replace the specific type String with T , and declare <T> :

java
public class Pair<T> {
    private T first;
    private T last;
    public Pair(T first, T last) {
        this.first = first;
        this.last = last;
    }
    public T getFirst() {
        return first;
    }
    public T getLast() {
        return last;
    }
}

Once you are proficient, you can start writing directly from T .

Static method

When writing a generic class, special attention should be paid to the fact that the generic type <T> cannot be used for static methods. For example:

java
public class Pair<T> {
    private T first;
    private T last;
    public Pair(T first, T last) {
        this.first = first;
        this.last = last;
    }
    public T getFirst() { ... }
    public T getLast() { ... }

    // Use <T> for static methods:
    public static Pair<T> create(T first, T last) {
        return new Pair<T>(first, last);
    }
}

The above code will cause a compilation error, we cannot use the generic type T on the method parameters and return type of the static method create() .

Some students searched online and found that you can add <T> after the static modifier, and the compilation will pass:

java
public class Pair<T> {
    private T first;
    private T last;
    public Pair(T first, T last) {
        this.first = first;
        this.last = last;
    }
    public T getFirst() { ... }
    public T getLast() { ... }

    // Can be compiled and passed:
    public static <T> Pair<T> create(T first, T last) {
        return new Pair<T>(first, last);
    }
}

But in fact, this <T> has nothing to do with the Pair<T> type <T> .

For static methods, we can rewrite them as "generic" methods separately, just use another type. For the create() static method above, we should change it to another generic type, for example, <K> :

java
public class Pair<T> {
    private T first;
    private T last;
    public Pair(T first, T last) {
        this.first = first;
        this.last = last;
    }
    public T getFirst() { ... }
    public T getLast() { ... }

    // Static generic methods should be differentiated using other types:
    public static <K> Pair<K> create(K first, K last) {
        return new Pair<K>(first, last);
    }
}

This will clearly distinguish the generic type of static methods from the generic type of instance types.

Multiple generic types

Generics can also define multiple types. For example, if we hope that Pair does not always store two objects of the same type, we can use the types <T, K> :

java
public class Pair<T, K> {
    private T first;
    private K last;
    public Pair(T first, K last) {
        this.first = first;
        this.last = last;
    }
    public T getFirst() { ... }
    public K getLast() { ... }
}

When using it, you need to point out two types:

java
Pair<String, Integer> p = new Pair<>("test", 123);

Map<K, V> of the Java standard library are examples of using two generic types. It uses one type for Key and another type for Value.

Summary

When writing generics, you need to define the generic type <T> ;

Static methods cannot reference the generic type <T> , and other types (such as <K> ) must be defined to implement static generic methods;

Generics can define multiple types at the same time, such as Map<K, V> .

Writing generics has loaded