Search code examples
javacomparable

Generalization of Comparable interface


Identity Interface was implemented in the system years ago. At this point, we got the necessity that each Identity should be Comparable. One of the options is to add additional & Comparable type to Identity declaration:

interface Identity<K> {

}

class Handler<T extends Identity<?> & Comparable<T>> {

  Handler(T value) {
    Util.<T>handle(value);
  }
}

class Handler2<T extends Identity<?> & Comparable<T>> {

  Handler2(T value) {
    Util.<T>handle(value);
  }
}

interface Util {

  static <T extends Comparable<T>> void handle(T value) {
  }
}

One of the main disadvantages is that a huge amount of code should be enhanced with identical information (e.g. & Comparable). Much elegant solution would be to extend Comparable interface with Identity one:

interface Identity<K> extends Comparable<Identity<K>>{

}

But in this case Handler class will highlight a compilation error:

error: method handle in interface Util cannot be applied to given types; required: T#1 found: T#2 reason: explicit type argument T#2 does not conform to declared bound(s) Comparable where T#1,T#2 are type-variables: T#1 extends Comparable declared in method handle(T#1) T#2 extends Identity declared in class Handler

What are the possible solutions in this situation?


Solution

  • After changing Identity to what you suggested

    interface Identity<K> extends Comparable<Identity<K>>{
    
    }
    

    You have two options. Either:

    class Handler<T, U extends Identity<T>>
    {
        Handler(U value) {
            Util.handle(value);
        }
    }
    

    Sample usage:

    Handler<String, Identity<String>> stringHandler = new Handler<>(new FooIdentity());
    

    or

    class Handler<T>
    {
        Handler(Identity<T> value)
        {
            Util.handle(value);
        }
    }
    

    Sample usage:

    final Handler<String> stringHandler = new Handler<>(new FooIdentity());
    

    And Util can remain unchanged.