Generics in Java

Generics in java means parameterized types to deal with type-safe objects. It allows type like Integer, String, …etc., and user-defined types to be a parameter to methods, classes, and interfaces.
Class, method, or interface which operates on this parameterized type is called a Generic entity.
Note: Generics cannot work with primitive types.
The following example illustrates the use of generics wherein the Player class is an abstract class. FootballPlayer and BasketballPlayer are the classes that manage the players of the football team and basketball team respectively. Both of these classes extend Player class which contain property shared by both of the class. Class Team contains the functionality to manage the activities of all teams.
Player.java
public abstract class Player {
private String name;
public Player(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
FootballPlayer.java
public class FootballPlayer extends Player {
public FootballPlayer(String name) {
super(name);
}
}
BaseballPlayer.java
package com.example.java.generics.model;
public class BaseballPlayer extends Player {
public BaseballPlayer(String name) {
super(name);
}
}
Team.java
Here Team class accepts the generic type as a parameter:
public class Team<T extends Player> {
private String name;
int played = 0;
int won = 0;
int lost = 0;
int tied = 0;
private ArrayList<T> members = new ArrayList<>();
public Team(String name) {
this.name = name;
}
public String getName() {
return name;
}
public boolean addPlayer(T player) {
if (members.contains(player)) {
//No need to typecast here as <T extends Player>.
System.out.println(player.getName() + " is already in this team");
return false;
} else {
members.add(player);
System.out.println(player.getName()+ "Picked for this team");
return true;
}
}
public int numPlayers() {
return this.members.size();
}
public void matchResult(Team<T> opponent, int ourScore, int theirScore) {
String message;
if(ourScore > theirScore) {
won++;
message = " Beat ";
} else if (ourScore == theirScore) {
tied++;
message = " Drew with ";
} else {
lost++;
message = " Lost to ";
}
played++;
if (opponent != null) {
System.out.println(this.getName() + message + opponent.getName());
opponent.matchResult(null, theirScore, ourScore);
}
}
public int ranking() {
return (won * 2) + tied;
}
}
Team<T extends Player> implies Team class accepts parameter of type Player and the classes that extends Player class. In our case both FootballPlayer and BaseballPlayer.
Team<T> implies class accepts the generic parameter but we need to type cast to respective type when using the respective type.
Generics.java (main class)
public class Generics {
public static void main(String args[]) {
Team<FootballPlayer> starKins = new Team<>("StarKins");
FootballPlayer fb = new FootballPlayer("FB");
starKins.addPlayer(fb);
Team<FootballPlayer> wideWings = new Team<>("WideWings");
FootballPlayer ob = new FootballPlayer("OB");
wideWings.addPlayer(ob);
Team<BaseballPlayer> baseBallTeam = new Team<>("Sunrisers");
BaseballPlayer bb = new BaseballPlayer("BB");
baseBallTeam.addPlayer(bb); //Comparing Football teams "starKins" and "Sunrisers".
starKins.matchResult(wideWings, 2, 1);
System.out.println("Rankings");
System.out.println(starKins.getName() + " : " + starKins.ranking());
System.out.println(wideWings.getName() + " : " + wideWings.ranking());
}
}
- We can specify multiple classes in the generic type declaration like this :
public class Team<T extends Player & Coach & Manager>
Why use Generics:
- Individual typecasting is not needed.
- It allows code reusability.
- It provides compile-time safety.
Complete code for this available at : https://github.com/SHRADHA-YEWALE/Java-features/tree/Generics