Multi-typed Parameters

In some cases you want to define a method parameter which is of a certain type (i.e a class or an interface), but also implements another interface.

Start Situation

If the first type is a class, the basic situation looks like (1):

class A 
{
    String getMyA();
}
interface B 
{
    String getMyB();
}

Now you have classes which do combine both of the above (2):

class C
 extends A
 implements B
{
}
class D 
 extends A
 implements B 
{
}

Finally you want to implement the following (3):

class X 
{
  static String getAB(/*C or D*/ object) {
      return object.getMyA() + object.getMyB();
  }
}

and use it like (4);

// somewhere else
C foo = new C();
System.out.println(X.getAB(foo));
D bar = new D();
System.out.println(X.getAB(bar));

Problem is how to implement the C or D type in the getAB() method. Indeed C or D is misleading and too special. What you really want is a type which is both A and B.

Good Solution

This requires at least Java 5. Here you can use a generic type parameter to your help. You only have to change (3) to look like:

class X 
{
  static <T extends A & B> String getAB(T object) {
      return object.getMyA() + object.getMyB();
  }
}

This is elegant and requires just a simple change at the place where it ought to be.

Of course this works for non-static methods the same, also for generic classes, and easily extends to more than 2 types. So it’s one of the patterns you should keep in your mental toolbox.

Special Cases

In time-critical code you should keep in mind that each access to object’s methods in getAB() internally uses a cast. What the above code really looks like is similar to:

class X 
{
  static String getAB(Object object) {                        // Java view of code, not your implementation
      return ((A)object).getMyA() + ((B)object).getMyB();     // Java view of code, not your implementation
  }
}

Casts are (nowadays moderately) expensive, so if you access the object several times in time-critical code you should do the unpacking ourself once:

class X 
{
  static <T extends A & B> String getAB(T object) {
      A a = object;  // here the cast is happening once
      B b = object;  // here the other cast is happening
      // --- from here only access a and b ---
      return a.getMyA() + b.getMyB();
  }
}

Java optimization might be able to figure this out, too, but I’d prefer to be sure.

Bad Solutions

Before Java 5 you had only two options: insert a common base class or extend the method getAB() to accept two parameters.

But if you are using a modern Java implementation: Don’t do this!

Insert a Common Base Class (deprecated)

(1) and (4) above stay the same, but (2) now looks like

class Base 
  extends A                                                      
  implements B 
{
}
class C extends Base {}
class D extends Base {}

and (3) becomes

class X 
{
  static String getAB(Base object) {
      return object.getMyA() + object.getMyB();
  }
}

In some cases this might even clarify your class structure, but in other cases this would insert an otherwise useless class or interface making things unnecessarily complex.

Inserting a class can even be impossible. This happens for code from libraries, and also for a very special case I encountered:

enum C implements B { /* ... */}

enum D implements B { /* ... */}

Both C and D extend Enum, and I wanted to write a method which only accepts enums implementing the special interface B. Of course you now know how I did it:

public <E extends Enum<E> & B> void foo(E e) { // ...

Make the Method Take Two Parameters (deprecated)

(1) and (2) stay the same, (3) becomes

class X 
{
  static String getAB(A a, B b) {
      return a.getMyA() + b.getMyB();
  }
}

and in (4) you’ll have to duplicate the parameter

// somewhere else
C foo = new C();
System.out.println(X.getAB(foo, foo));
D bar = new D();
System.out.println(X.getAB(bar, bar));

This is obviously awkward, but removes the need to change the class structure in cases where this is impossible or not preferable.