IntelliJ is showing me context hints that my variables are of type (String..String?)
. I cannot find any mention of it on the internet, what is this type?
(String..String?)
represents a flexible type with lower bound String
and upperbound String?
(nullable string). This is not valid Kotlin code (it's not denotable) but it is used in the compiler internals and thus in IntelliJ's hints sometimes.
(On the JVM we often see platform types using !
as in String!
, which are a more specific case of flexible types)
It's Kotlin's way of saying it doesn't know whether the String
type declared for payload.email
is nullable or not (for instance if this is declared in Java, which doesn't distinguish those), and yet it doesn't want to enforce either of those, for convenience (hence "flexible").
As the name suggests, flexible types are flexible — a value of type (L..U) can be used in any context, where one of the possible types between L and U is needed
This means that even though the actual type of the value is "somewhere between String
and String?
", values of this type can be used even in places expecting String
, even though the real type of that value may be String?
and thus the value could be null.
This is useful because assuming it is String
would mean that null checks would be marked as redundant, and assuming it is String?
would force the developer to write null checks everywhere, even though they might know that this particular Java method cannot return null.
In general, it's a good practice to explicitly declare the type of a variable that you get from Java, to avoid the propagation of the platform type and the uncertainty (and unsafety) that comes with it:
val email: String = payload.email // if you know it cannot be null
val email: String? = payload.email // if you don't know
© 2022 - 2024 — McMap. All rights reserved.
payload.email
? – Momentumpublic String getEmail()
. It might be a Java-Kotlin translation – AccouchementString!
because Kotlin cannot know if these platform types are nullable or not. Maybe that is a different notation for it? It would make some sense, meaning any type between non-nullable and nullable String. However, I've never seen this representation myself. – MomentumString!
to denote platform types, which is not valid Kotlin syntax either. – Momentumval email: String? = payload.email
? – Momentumemail is String
andemail is String?
return? 2xtrue means it's String, false true that it's String?, 2xfalse - no clue (see pl.kotl.in/ymOft6Bp7). My gut feel says it's related to the Java not being null specific – Rappis
checks will depend on the current value returned bypayload.email
, not its type. So you'll gettrue
/true
if email is not null at this moment, and getfalse
/true
if email is null. In the first case, you can't assume the string could never have been null. You can't know the actual intended type unless you look at the corresponding Java code and its invariants/intention – Flagella