Yes, if you have a parameterized type declared as MyClass<T> then T could be nullable. And if you need to work with not null values only, then you need to declare it as: MyClass<T : Any>.
I’m not sure, why do you say that you can’t rely on the compiler for null-safety here. If you allowed null values then you need to handle them
Also, your example is very misleading and I’m not sure if you did this intentionally or not. I just want to make sure that you are aware that your jump() function isn’t at all related to strings and it could receive any Down instance? x could be nullable, it could be an integer, etc.
It seems a bit confusing that return type says Down<String>. Yet I can still have a null reference Down.x. I would somehow expect to be forced to say Down<String?> . Or otherwise not be allowed a x <-null
I mean similarly to how you treat non-generics eg Animal vs Animal? ? Maybe my lack of understanding some key concepts here?
Ok, so I guess your example wasn’t intentional, but it was a mistake
By doing this: fun <String> you declared a parameter type String, overriding class String. This function has nothing to do with strings. It is an equivalent of:
fun <T> jump(x : Down<T>):Down<T>
So it can receive and return any Down objects, including ones where T is nullable. If you want your jump() function to work only with strings and only non-nullable, then just remove <String>. You will notice that you are no longer able to pass Down(null) to it and you can be sure that x is not null.
Ah yes. That was my mistake. I actually started from fun <T> jump(x : Down<T>):Down<T>, but I forgot to carry the 1 and ended up in a totally different place