Generic Types are Classes or Interfaces that uses Generics
Let’s convert this interface:
public interface SomeBehaviour {
Object behaviour(Object a, Object b);
}
To a Generic Type Interface:
public interface SomeBehaviour<T> {
T behaviour(T a, T b);
}
What is <T>
?
The angle brackets are the syntax for declaring that this Class/Interface uses generics.
T
is known as a generic type parameter, which is just a placeholder for an actual object type!
The name is kinda self explanatory…
There’s nothing special about the character T
.
The code bellow is perfectly valid!
public interface SomeBehaviour<hehe> {
hehe behaviour(hehe a, hehe b);
}
However, Java provides conventions for how we should name our generic types:
- E - Element: the type will be part of a collection, like List<E>, Set<E>
- K - Key: the type is used as a key in the class, like Map<K,V>
- V - Value: the type is used as a value in the class, like Map<K,V>
- N - Number: the type is a number, when used, N should always extend Number
- T - Type: general name for a generic type
- S, U, V etc. - 2nd, 3rd, 4th types: when T is already used
How do we use generics?
Simply substitute T
for the chosen type!
public class MyImplementation implements SomeBehaviour<String> {
@Override
String behaviour(String a, String b) {
//... implementation details
}
}
// or!
public abstract class MyAbstractImplementation<T> implements SomeBehaviour<T> {
@Override
String behaviour(T a, T b);
}
What does that do?
By using generics we can now have explicit type safety!
The SomeBehaviour
interface now inherently forces its implementations to specify a type T
and ensures that both parameters of the behaviour
function and its return type are of the type that was specified.
We can even accept multiple generic types!
public interface AnotherBehaviour<T, S> {
void behaviour1(T a, S b);
S behaviour2(T a);
}
This has its uses in Interfaces such as Map<K,V>
! Where the key and value may be different types!