Java interfaces and return types

If the return type must be the type of the class that implements the interface, then what you want is called an F-bounded type:

public interface A<T extends A<T>>{ public T b(); }

public class C implements A<C>{
  public C b() { ... }
}

public class D implements A<D>{
  public D b() { ... }
}

In words, A is declaring a type parameter T that will take on the value of each concrete type that implements A. This is typically used to declare things like clone() or copy() methods that are well-typed. As another example, it’s used by java.lang.Enum to declare that each enum’s inherited compareTo(E) method applies only to other enums of that particular type.

If you use this pattern often enough, you’ll run into scenarios where you need this to be of type T. At first glance it might seem obvious that it is1, but you’ll actually need to declare an abstract T getThis() method which implementers will have to trivially implement as return this.

[1] As commenters have pointed out, it is possible to do something sneaky like X implements A<Y> if X and Y cooperate properly. The presence of a T getThis() method makes it even clearer that X is circumventing the intentions of the author of the A interface.

Leave a Comment