Is there an alternative way to specify an additional boundary when the first boundary is a type parameter?

I know that specifying an extra boundary when the first bound is a type parameter is not possible in Java; however, I was wondering if anyone knows an alternative way to do something like this and save it during compilation? I gave an example below.

In the following code, I mean the following: <E extends T & Comparable<T>> . In this situation, I want to be able to use the built-in comparator if type T comparable, otherwise I want to specify my own comparator.

Is there an alternative way to do this while maintaining type safety at compile time?

 public class ExampleClass<T, U> { [...] public <E extends T & Comparable<T>> ExampleClass(Function<U, E> function) { this.function = function; this.comparator = (E a, E b) -> a.compareTo(b); } public ExampleClass(Function<U, T> function, Comparator<U> comparator) { this.function = function; this.comparator = comparator; } } 
+6
source share
1 answer

You can solve your problem by implementing the first constructor as a static method that delegates your second constructor, for example:

 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); } } 

A static function does not have access to parameters like T and U, therefore it defines new independent ones. The return type is now Test<E,V> , where E implements Comparable and V is unlimited, like your U-parameter.

+3
source

All Articles