What is the difference between nullabe and non-nullable type in Kotlin - kotlin

Please explain the difference between nullable and non-nullable type. I am new to kotlin and i am confused. Thanks

Nullable types can hold nulls. When type is nullable the question mark is set after it's type:
val str: String? = null
Non-nullable types can't hold nulls:
val str: String = "some value"
If we try to set null value to Non-nullable type, IDE will give an error and code will not be compiled:
val str: String = null // error, the code won't compile
Here you can read more about Null Safety.

when a variable has a nullable type then the variable can have value or it can also have value null and the program will not force close like most java based programs with null pointer exeption error messages.
for example :
val data: DataResponse? = null
its more save then you use val data: String because when your data variabel dont have value or null when you use it your program not force close at that time.
you can use your data variabel like this:
your_text.text = data
and your code will not force close.
but if your code like this, it means nonNullable.
val data: DataResponse
your apps will force close at that time you use your variabel

Related

Why does defining a nullable variable in a separate line change Kotlin compiler behavior?

// first piece of code start
var name1: String?
name1 = null
println(name1!!.length) // Unresolved reference: length
// first piece of code end
// second piece of code start
var name2: String? = null
println(name2!!.length)
// second piece of code end
When I hover my house over the "length" in the first piece of code, I get the message "Unresolved reference: length", and also "length" is in red. So, I figure out that the compiler already knows it is null and hence the message.
But doesn't the compiler already know that "name2" is also null? Why is not the length in the second piece of code not in red and there is no "Unresolved reference: length" message when I hover my mouse on the "length"?
The first piece of code doesn't even compile due to unresolved reference, but the second one does, and throws an exception.
Can someone explain why Kotlin compiler behaves in this way? I am using IntelliJ if it matters.
I don't have any formal confirmation or documentation to link to, but apparently, for the Kotlin compiler this is like:
var name1: String?; name1 = null - create a variable of type: String?, then assign a null to it (smart cast)
var name2: String? = null - create a null value, then assign it to a variable of type: String?.
As a result, in the first example the inferred type is null (technically, it is Nothing?) and in the second it is String?. The same happens in the opposite situation:
var name1: String?
name1 = "value"
println(name1.length) // allowed, `name1` is `String`
var name2: String? = "value"
println(name2.length) // not allowed, `name2` is `String?`
To be honest, I'm not a huge fan of this behavior. I see the logic in this, as in both cases the order of operations is conceptually different. But I don't see a reason to not infer/smart-cast the type and this behavior forces the developer to split a simple operation into two lines.

How to safe-cast a null into a generic type <T>?

I want to know if there's a way to make a safe cast from null, the next example throws an UNCHECKED CAST warning:
fun <T> notInitialized(): T = null as T
So, If anyone has an idea of how to make a safe cast from this function please let me know!
You can do fun <T> notInitialized(): T? = null - you need to return a nullable type (otherwise your cast is explicitly unsafe), and since you're already specifying the return type you don't need to cast null as T?. Or you could do that and skip the return type, fun <T> notInitialized() = null as T?
Either way you're just returning null, which isn't any specific type - you're just telling the caller to treat it as one. And that type needs to be nullable
As an alternative to the generic answer (which is the usual way to approach these things), you could do this:
fun notInitialised(): Nothing? = null
Nothing is the ‘bottom’ type, which has no values and is the subset of all other types. So Nothing? is a type with just one value (null), and is a subtype of all nullable types. This means you can assign it to any nullable type without needing any type inference, e.g.:
val a: Int? = notInitialised()
But I still don't understand the purpose of this — it doesn't seem to have any benefit over just using null directly. If you're using null to represent an uninitialised value (as opposed to an unknown value, a missing value, an inapplicable value, an unavailable value, an undefined value, an unchanged value, a secret value, or any of the other subtly-different things that people use null to mean), then that should be spelled out in the property/method/variable's doc comment — in which case there's no point spelling it out again in the code.

Is it possible to enforce nullability of template?

I want to have something like this to runtime check a nullable value isn't null in debug builds, a debug assert, just like C/C++ projects convention of having such different level of asserts,
val <T> T.debugAssertNotNull: T
get() = this ?: throw NullPointerException("A debug only assert has happened")
This works fine except it was just more nice if this T automatically was able to only accept nullable values or to hint at least when a not null value is passed
"123".debugAssertNotNull
or when "?." accidentally is used instead ".",
val a: String? = null
val b = a?.debugAssertNotNull
was passed used, is that possible or every not null type is inherited from its nullable variant anyway thus making this impossible?

Why should I assign the data type of variables in Kotlin if giving it values initially it is capable of inferring the data type of the variable

As mentioned in the code provided. My question is if there is any advantage by mentioning the data type early on when I am just giving the variable it's value. As said in line 2 it can understand that it is int type.
val a: Int = 1 // immediate assignment
val b = 2 // `Int` type is inferred
val c: Int // Type required when no initializer is provided.
A few reasons you might want to specify a type explicitly:
You want a supertype of the value (perhaps so you can to reassign it later), e.g.:
var myList: List<String> = ArrayList<String>()
You want to protect against changes to other code (especially if it's outside your control), e.g.:
val x: MustBeThisType = SomeLibrary.getValue()
(That would give an error if SomeLibrary.getValue() ever changes to returns something other than MustBeThisType or a subtype.)
You want to avoid an explicit numeric conversion, e.g.:
val x: Long = 2
instead of:
val x = 2.toLong()
You want to make it very clear to someone reading your code (especially if that might not be in an IDE).
As Michael says, you may need to specify the nullability of types returned from Java, e.g.:
val x: String = someJavaClass.getAString() // Never returns null
None of those is particularly common in my experience, though.

What is the Kotlin double-bang (!!) operator?

I'm converting Java to Kotlin with Android Studio. I get double bang after the instance variable. What is the double bang and more importantly where is this documented?
mMap!!.addMarker(MarkerOptions().position(london).title("Marker in London"))
This is unsafe nullable type (T?) conversion to a non-nullable type (T),
!! will throw NullPointerException if the value is null.
It is documented here along with Kotlin means of null-safety.
Here is an example to make things clearer.
Say you have this function
fun main(args: Array<String>) {
var email: String
email = null
println(email)
}
This will produce the following compilation error.
Null can not be a value of a non-null type String
Now you can prevent that by adding a question mark to the String type to make it nullable.
So we have
fun main(args: Array<String>) {
var email: String?
email = null
println(email)
}
This produces a result of
null
Now if we want the function to throw an exception when the value of email is null, we can add two exclamations at the end of email. Like this
fun main(args: Array<String>) {
var email: String?
email = null
println(email!!)
}
This will throw a KotlinNullPointerException
Not-null assertion operator
Kotlin's double-bang operator is an excellent sample for fans of NullPointerException (NPE).
The not-null assertion operator !! converts any value to a non-null type and throws an exception if the value is null.
val nonNull = str!!.length
If you write str!!, it'll return a non-null value of str (str is a String? here) or throw an NPE if str is null. This operator should be used in cases where the developer is guaranteeing – the value will never be null. If you want an NPE, you have to ask for it explicitly.
!!(Double Bang) operator is an operator to assert forcibly nullable variable as not null.
Example:
Here str is a string with value. But its nullable. Since its nullable we need to handle null for avoid compile time exceptions.
val str :String? = "Foo"
val lowerCase = str!!.lowerCase()
Here if we add !! operator, since it has non null value it would work and lowercased value will be assigned.
val str :String? = "Foo"
str = null
val lowerCase = str!!.lowerCase()
But here if you assign null value and use the particular value , it will throw KotlinNullPointerException.
One important thing here is, in most of the cases one should avoid as !! operator unless if its 100% sure that value is non null value or if the exception is caught and handled properly.
If you need to avoid this NPE, you can use null safe operators with elvis operators. null safe call ?. opertators with elvis are better way to handle null safety in kotlin.
You can read more about Kotlin null safety here
!! is an assertion that it is not null. Two exclamation marks after a nullable value convert it to a non-nullable type. At the same time, before the conversion, it is not checked in any way that the value really does not contain null. Therefore, if during the execution of the program it turns out that the value that the !! operator is trying to convert is still null, then there will be only one way out - to throw a NullPointerException.
Java
throws NullPointerException
Kotlin
simply use !!
This would help for understanding
It means in human language: I promise I will assign value later, but please don't worry for now my variable. On the other it is non-null variable terminologically.