Richard Kraft bio photo

Richard Kraft

Richard is an engineer focused on providing maintainable business solutions that scale well

Email Github

Have you ever needed to enforce that a List implements RandomAccess? There is a better solution than using “instanceof.” Let’s take a look at how generics can make multiple inheritance more accessible in Java.

Given two interfaces, how do you enforce that a method parameter extends both?

public interface A {
    String methodOne();
}

public interface B {
    String methodTwo();
}

public class Processor {
    public void doStuff(Object parameter) {
        // parameter extends both A and B, or the next two lines will throw a ClassCastException
        A objectA = (A) parameter;
        B objectB = (B) parameter;
    }
}

One way is to create a third interface that extends both interfaces and use that.

public interface AB extends A, B {
}

public class Processor {
    public void doStuff(AB parameter) {
    }
}

The problem with this solution is that you now have this interface that serves no real purpose.

As an alternative, we can use generics to enforce this at compile time and get rid of the additional interface entirely.

public class Processor {
    public <T extends A & B> void doStuff(T parameter) {
        parameter.methodOne();
        parameter.methodTwo();
    }
}

This comes in handy when we want to enforce that a List object is optimized for indexed access. We know that accessing the entries by index efficiently.

public void <T extends List<String> & RandomAccess> doStuff(T orderedList) {
    for (int i=0; i < orderedList.size(); i++) {
        System.out.println(orderedList.get(i));
    }
}

This shows how we can safely implement multiple inheritance. The Java compiler enforces that the entries after the ampersand are all interfaces.