Generic InterfacesJ8 Home « Generic Interfaces
With generics we can create our own generic interfaces which allow us to create generalized interfaces, same interface rules apply, with all the type safety that generics gives us.
When creating your own generic types it is best practice to use pneumonics for the formal type parameter rather than multiple letters.
Following is a simple generic interface and class so you can see how we can create a generic interface and implement it. We are using T as the placeholder for our formal type parameter in this instance, which you can think of as a pneumonic for Type. For a collections example we would use the E pneumonic for Element.
package info.java8;
/*
Simple generic interface that accepts any object
*/
interface SimpleGenericInterface<T> {
// Implementation will show object type
void showObjectType();
}
In the overridden showObjectType()
method below we are using the getClass()
method of Object
to get the actual Class type which we chain to getName()
, which is a method of the Class
object, which can be found in the java.lang
package, then print this to the console. Notice how we use the T formal type parameter within the declaration and constructor.
package info.java8;
/*
Simple generic class that implements SimpleGenericInterface
*/
public class SimpleGenericInterfaceImpl<T> implements SimpleGenericInterface<T> {
// Generic object declaration
private final T genericObj;
// Pass reference to object of type T to our constructor
public SimpleGenericInterfaceImpl(T genericObj) {
this.genericObj = genericObj;
}
// Output object type of T to console
public void showObjectType() {
System.out.println("Object type of T is " + genericObj.getClass().getName());
}
}
Now we need to write a test class to show how we can pass various objects to our SimpleGenericInterfaceImpl
class:
package info.java8;
/*
Test our SimpleGenericClass class that accepts any object
*/
public class TestSimpleGenericInterfaceImpl {
public static void main(String[] args) {
// Test the SimpleGenericInterfaceImpl using a String object
SimpleGenericInterfaceImpl<String> genStringObj = new SimpleGenericInterfaceImpl<>("ab");
genStringObj.showObjectType();
// Test the SimpleGenericInterfaceImpl using an Integer object
SimpleGenericInterfaceImpl<Integer> genIntegerObj = new SimpleGenericInterfaceImpl<>(1);
genIntegerObj.showObjectType();
// Test the SimpleGenericInterfaceImpl using a Double object
SimpleGenericInterfaceImpl<Double> genDoubleObj = new SimpleGenericInterfaceImpl<>(1.2);
genDoubleObj.showObjectType();
}
}
Running the TestSimpleGenericInterfaceImpl
class in IntelliJ produces the following output:
So from the screenshot you can see that our TestSimpleGenericClass
class works with the various objects passed to it replacing the T formal type parameter placeholder with the actual type parameter
of the object passed. We mentioned ealier that the compiler inserts the casts required to make generics work when we run our bytecode. What we haven't mentioned yet is that generic code is implemented
by erasure, which means that generic code enforces type constraints only at compile time. The element type information is erased in the runtime bytecode, which is how legacy code can freely
interoperate with generic code. So the point here is that at runtime there is only one version of the SimpleGenericInterfaceImpl
class that works through the casts inserted automatically by the
compiler into the runnable bytecode.
Generally if a class implements a generic interface then that class must be generic as well, so that it takes a type parameter that is passed to the interface. If an actual parameter is used when implementing the interface, then the class doesn't have to be generic. The following code snippet should clarify this:
package info.java8;
// Following is correct as used above
public class SimpleGenericInterfaceImpl<T> implements SimpleGenericInterface<T> {
// Following is incorrect as no type specifed for class and formal type parameter specified
public class SimpleGenericInterfaceImpl implements SimpleGenericInterface<T> {
// Following is fine as actual type specified for implementation, so class is not generic
public class SimpleGenericInterfaceImpl implements SimpleGenericInterface<String> {
Related Quiz
Generics Quiz 3 - Generics Interfaces Quiz
Lesson 3 Complete
In this lesson we looked at generics interfaces and how to use them.
What's Next?
In the next lesson we look at generic classes.