Java Question

Is there an alternate way to specify an additional bound when first bound is a type parameter?

I know that specifying an additional bound when the first bound is a type parameter is not possible in Java; however, I was wondering if anybody knows an alternate way to do something similar and to keep it safe at compile time? I've provided an example below.

In the following code what I'm referring to is this:

<E extends T & Comparable<T>>
. In this situation, I want to be able to use the inbuilt comparator if the type of
T
is comparable, otherwise, I want to specify my own comparator.

Is there any alternate way to do this while keeping type-safety at compile time?

public class Class<T, U> {
[...]

public <E extends T & Comparable<T>> Constructor(Function<U, E> function) {
this.function = function;
this.comparator = (E a, E b) -> a.compareTo(b);
}

public Constructor(Function<U, T> function, Comparator<U> comparator) {
this.function = function;
this.comparator = comparator;
}

}

Answer

You can solve your problem by implementing the first constructor as a static method that delegates to your second constructor, like this:

import java.util.Comparator;
import java.util.function.Function;

public class Test<T,U> {
  private final Function<U,T> function;
  private final Comparator<T> comparator;

  public Test(Function<U,T> function, Comparator<T> comparator) {
    this.function = function;
    this.comparator = comparator;
  }

  public static <E extends Comparable<E>, V> Test<E,V> withNatOrder(Function<V,E> function) {
      // Any of these two will do
      final Comparator<E> comp = (E a, E b) -> a.compareTo(b);
      final Comparator<E> comp2 = Comparator.naturalOrder();
      return new Test<>(function, comp);
  }
}

The static function does not have access to the class type parameters T and U, so it defines new, independent ones. The return type is now Test<E,V> where E does implement Comparable and V is unbounded like your U parameter.