DEV Community

Cover image for What does <T> mean in Java?
Maddy
Maddy

Posted on • Updated on

What does <T> mean in Java?

< T > is a conventional letter that stands for "Type", and it refers to the concept of Generics in Java. You can use any letter, but you'll see that 'T' is widely preferred.

WHAT DOES GENERIC MEAN?

Generic is a way to parameterize a class, method, or interface.

Let's look at an example:

package Generics;

class House<T>{

    T doorNumber;

    public House(T doorNumber) {
        this.doorNumber = doorNumber;
    }

    public void print(){
        System.out.println("Your house number is: " + this.doorNumber);
    }
}

Enter fullscreen mode Exit fullscreen mode
  • We have a class called "House" that can accept an unspecified Object type.
  • Then, we have a field called doorNumber, which as well can accept any Object type.
  • In the end, we declare a parameterized constructor, and we print out the door number.

In short, the user can decide whether this door number is an Integer, a String, a Float, etc.

NOTE: you can only use Objects. Primitives are not supported, because Generics are intended to be a feature used at compile-time. When we use Generics, the T goes away in place of anything that can extend the Object class, and primitives don't have this trait.

Let's say that we want the doorNumber to be a String.

public class GenericsExample {
    public static void main(String[] args) {
        House<String> mainHouse = new House<>("14a");
        mainHouse.print();

    }
}
Enter fullscreen mode Exit fullscreen mode

The outcome would be:

Your house number is: 14a
Enter fullscreen mode Exit fullscreen mode

We would replace the 'T' with "String" and enter the house number in the constructor.

We can use multiple types if, for example, we want the class to accept more than one Object. We can add another letter to say that we want the class to accept another Generic.

package Generics;

class House<T, V>{

    T doorNumber;
    V streetName;

    public House(T doorNumber, V streetName) {
        this.doorNumber = doorNumber;
        this.streetName = streetName;
    }

    public void print(){
        System.out.println("You live at: " + this.doorNumber + " " + this.streetName);
    }
}

public class GenericsExample {
    public static void main(String[] args) {
        House<Integer, String> mainHouse = new House<>(14, "Tellson Avenue");
        mainHouse.print();

    }
}
Enter fullscreen mode Exit fullscreen mode

The outcome would be:

You live at: 14 Tellson Avenue
Enter fullscreen mode Exit fullscreen mode

So far we've seen examples of a Generic used at the class level. But we can also have Generic methods and interfaces.

Generic method

package Generics;

class House{

    public <T> void print(T doorNumber){
        System.out.println("You live at house number: " + doorNumber);
    }

}

public class GenericsExample {
    public static void main(String[] args) {
        House mainHouse = new House();
        mainHouse.<Integer>print(14);

    }
}

Enter fullscreen mode Exit fullscreen mode

The method accepts any type of Object, and it prints out the doorNumber which will be of any Object type. In this case, we want the method to accept an Integer.

The outcome would be:

You live at house number: 14
Enter fullscreen mode Exit fullscreen mode

Generic interface

First, create an interface.

package Generics;

interface Property<T>{
    void hasBalcony(T balcony);
}
Enter fullscreen mode Exit fullscreen mode

Then, implement the interface.

package Generics;

public class House implements Property<String> {

    @Override
    public void hasBalcony(String balcony) {
        System.out.println("Is there a balcony in the room? " + balcony);
    }

    public static void main(String[] args) {
        House mainHouse = new House();
        mainHouse.hasBalcony("YES");
    }

}

Enter fullscreen mode Exit fullscreen mode

The outcome is:

Is there a balcony in the room? YES
Enter fullscreen mode Exit fullscreen mode

What are the benefits of using Generics?

  1. Better compile-time checking: if you use an Object type different from the one that you specified, the compiler will tell you.
  2. Reusability: you can use a class, method or interface multiple times, because you decide which Object type to apply based on what you're trying to achieve.
  3. It's great for data structures and algorithms: ArrayList and Hashmap are a couple of examples that make use of Generic.

You've reached the end of this article! Subscribe to my newsletter for more articles about this and other topics! 😊

Discussion (0)