< 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);
}
}
- 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();
}
}
The outcome would be:
Your house number is: 14a
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();
}
}
The outcome would be:
You live at: 14 Tellson Avenue
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);
}
}
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
Generic interface
First, create an interface.
package Generics;
interface Property<T>{
void hasBalcony(T balcony);
}
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");
}
}
The outcome is:
Is there a balcony in the room? YES
What are the benefits of using Generics?
- Better compile-time checking: if you use an Object type different from the one that you specified, the compiler will tell you.
- 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.
- 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! 😊
Top comments (0)