What's the proper way to use Array<T?>


#1

Hi there,

The following code generate a compiler WARNING: ‘T’ has a nullable upper bound. This means that a value of this type may be null. Using ‘T?’ is likely to mislead the reader

What is a proper way to rewrite it so there is no WARNING?

class MyStack<T> {   private var currentIndex : Int = -1   private var elements = Array<T?>(16) { i -> null }

  private fun ensureCapacity() {
  if (currentIndex + 1 >= elements.size) {
           val tmp = elements
           elements = Array<T?>(elements.size + 2 * elements.size) { i -> null }
           for (i in tmp.indices)
           elements[i] = tmp[i]
  }
  }
}


Thanks
Zemian


#2

You can write: ``

class MyStack<T: Any> { ...


#3

Ah, that works. Thanks!

Would you able to explain to me why is that needed? It seems little un-intuitive to me.


#4

Perhaps You will find the answer here.


#5

Thanks for the link bashor. I have read through the comments on that Issue. So let me try to conclude my understand and see if I get this right.

  1. Kotlin defualt generic type parameter with nullable upper bound, so when I write “class MyStack<T>”, it’s equavalent to “class MyStack<T : Any?>”. This is done so it can fit existing Java API and backward compatible. Am I right?

  2. Now becuase of “class MyStack<T : Any?>”, and if I use things like “var elements = Array<T?>(16) { i -> null }” in the class body, the compiler issue warnings about “T?” because it might confuse user. So to get rid of the warning one can re-declare the clas to “class MyStack<T : Any>”. Am I right?

  3. With above change, how significant that has impact MyStack implementation? What I mean is that what is the real difference in behavior wise between “class MyStack<T : Any?>” to "“class MyStack<T : Any>”? This is not an easy concept for beginner to get and learn. As you can see, one is only interesting writing a Stack implementation, why should he/she care “T : Any” or “T: Any?” as generic type? Can Kotlin be improved on this area?

Thanks,
Zemian


#6

1. Yes 2. Yes 3. Why one should care: you are creating a library class, that must respect nulls or prohibit them, this is a part of the contract of the class, and the language makes you think about it. Feel free to suggest an improvement if you see one.