2

Let's say I have a generic class:

class OrderedArray<T>(
    private val items: Array<T>,
    private val comparator: Comparator<in T>
) {
    constructor(items: Array<T>) : this(items, naturalOrder<T>())
}

Of course this code does not compile as T is not necessarily comparable. Is there a language construct available which bounds the generic parameter of a type on a constructor? How could I allow to construct an instance of my class without explicitly passing the comparator when a natural ordering is available?

Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97

2 Answers2

4

There's no way to introduce a generic bound on a constructor because constructors don't have their own generic parameters, they can only use the class parameters.

Consider the following workarounds:

  • One solution is to make a subclass with the generic bound and use it:

    class NaturallyOrderedArray<T: Comparable<T>>(items: Array<T>) 
        : OrderedArray<T>(items, naturalOrder<T>())
    

    But it looks clumsy (write a class just to override a generic bound and introduce another constructor?!) and requires the parent class to be open or at least sealed.

  • You can make a factory function with the desired generic bound:

    fun <T: Comparable<T>> naturallyOrderedArray(items: Array<T>) = 
        OrderedArray(items, naturalOrder<T>())
    

    You might make the function mimic a constructor so that it would be called like OrderedArray(items), but it's better to keep to consistent naming that would also hint that the natural order is used.

Community
  • 1
  • 1
hotkey
  • 140,743
  • 39
  • 371
  • 326
1

I would write strait-forwardly:

class OrderedArray<T: Comparable<T>>(
    private val items: Array<T>,
    private val comparator: Comparator<in T> = naturalOrder<T>())

Does it solve the problem? If not, what are the limitations for your case?

voddan
  • 31,956
  • 8
  • 77
  • 87
  • The thing is that I would like my class to work with non-comparable T-s as well. Of course an explicit comparator must be provided in those cases. – Tamas Hegedus Mar 31 '16 at 15:15