1 Interfaces Can Be Generic Too
We have seen generic classes in Lesson 2 and generic methods in Lesson 3. Now let us see that interfaces can also be generic. In fact, you have already used a generic interface without realizing it!
Just like classes, interfaces can have type parameters. The syntax is exactly the same — you place the type parameter in angle brackets right after the interface name:
interface Name<T> declares a generic interface. The type parameter T can then be used throughout the interface as a placeholder for any type. When a class implements this interface, it specifies the actual type.
2 Remember Comparable? (Without Generics)
Remember the Comparable interface from Module 9 (Interfaces)? Before Java 5, it looked like this:
The compareTo method takes Object as its parameter. That means you can compare anything with anything — a String with a Date, an Integer with a Circle. The compiler cannot stop you.
Problem Comparing Apples with Oranges
Object and says "OK, that's fine." But at runtime, comparing a String with a Date makes no sense — this will throw a ClassCastException! The program crashes, and you only discover the bug when a user reports it.
3 Comparable with Generics
Starting with Java 5, the Comparable interface was redesigned using generics. Let us see the new version:
Now T is the type parameter. When a class implements Comparable<String>, the compareTo method only accepts String. No more Object — the compiler knows the exact type!
Example How String Implements Comparable<String>
Notice that compareTo now takes String — not Object. The generic type parameter T has been replaced with the concrete type String.
Safe Usage The Compiler Protects You
String with a Date. The compiler says: "No, you declared Comparable<String>, so you can only compare with String."
4 Side-by-Side Comparison
Let us put the old and new approaches side by side so you can see the difference clearly:
5 Creating Your Own Generic Interface
You are not limited to using Java's built-in generic interfaces. You can create your own! Let us build a simple Container<T> interface that defines a contract for storing and retrieving items of any type.
Step 1 Define the Generic Interface
Step 2 Implement the Interface
Notice that SimpleList<T> passes its own type parameter T to Container<T>. This means the implementing class remains generic — the user decides the type when creating a SimpleList object.
Step 3 Use It with Type Safety
ArrayList<E> works internally! The ArrayList class implements the List<E> interface, which is a generic interface. Now you understand the power behind it.
1. Keep it generic: class SimpleList<T> implements Container<T> — the class stays generic, and the user picks the type later.
2. Fix the type: class StringList implements Container<String> — the class locks in a specific type. Every method uses String directly.
6 Key Takeaways
-
1
Interfaces can be generic, just like classes:
interface Name<T> -
2
When implementing, specify the type:
implements Comparable<String> - 3 Generic interfaces enforce type-safe contracts — the compiler checks that both sides of the contract agree on the types
-
4
Comparable<T>prevents comparing incompatible types — no moreStringvsDatemistakes -
5
Java's built-in interfaces (
Comparable,Iterable,List, etc.) all use generics - 6 You can create your own generic interfaces to build reusable, type-safe abstractions