I'm unable to remove my NullPointerException error - kotlin

The below code
fun main(args: Array<String>) {
println("Enter your value : ")
try{
val(a, b, c) = readLine()!!.split(' ')
println("Values are $a $b and $c")
}catch(ex : IndexOutOfBoundsException){
println("Invalid. Missing values")
}
}
produces the following error in Kotlin Playground:
Enter your value:
Exception in thread "main" kotlin.KotlinNullPointerException at FileKt.main(File.kt:4)
I have seen other questions with NullPointerException but I am unable to resolve it. I might would have missed some so it would be really helpful if you can share useful links. Since I am new to Kotlin, it would be awesome if you correct my program.
Remark: I don't have any background on java either and most of the NullPointerException questions are based on java
Edit 1 : I have tried gidds' solution and it seems to be working except one minor fault. The readLine() is for some reason not working.
The below code
fun main(args : Array <String>){
val line = readLine()
try{
println("Output : $line")
if (line != null) {
val(a, b, c) = line.split(' ')
println("Values are $a $b and $c")
} else {
println("No values given...")
}
}
catch(ex : IndexOutOfBoundsException){
println("Invalid. Missing Values...")
}
}
produces the following error in Kotlin Playground :
Output : null
No values given...
I guess I was getting the previous errors due to the same reason, i.e. readLine() was not working properly and the user is not getting an opportunity to give input(s).

With readLine()!!, you are saying the compiler that if this returns null, that will crash with NullPointerException. In another way, you must be sure to have return value of readLine() to be not null. Read more about !! operator here.
The not-null assertion operator (!!) converts any value to a non-null
type and throws an exception if the value is null.
You can have null check with elvis operator like below:
try{
val(a, b, c) = readLine()?.split(' ')
println("Values are $a $b and $c")
}catch(ex : IndexOutOfBoundsException){
println("Invalid. Missing values")
}

To expand on the earlier answer, this is about how to handle nulls.
The problem is that readLine() can return null.  (This happens if end-of-file is reached; for example, if you redirect the input from a file, and reach the end of the file; or if it's taking input from the keyboard and you press Ctrl+D.)
The Kotlin compiler knows this.  (Nullability is built into Kotlin's type system.  readLine() returns a String? — the question mark indicates that the value could be null.)
Kotlin is very careful about null-safety, and won't let you do anything with the value that would fail if it's null.  So in your code, if you omit the !!, you get an error on the following ..  (‘Only safe (?.) or non-null asserted (!!.) calls are allowed on a non-nullable receiver of type String?’)
So you have to handle the null somehow.
Appending the not-null assertion !! effectively promises the compiler that you know better, and that it can never be null.  This is usually a bad idea (which is why that operator was designed to look ugly); in practice, you generally don't know better than the compiler, and it will trip you up — as you've discovered!  In your case readLine() did return null, and so the !! operator threw a KotlinNullPointerException.
So, you need a better way to handle it.
The traditional way is an explicit check, e.g.:
val line = readLine()
if (line != null) {
// Within this block, the compiler knows that line
// cannot be null.
} else {
println("No values given.")
}
This is a good, clear, general approach.  And it may be the best approach in your case.  (You'd still need to catch the IndexOutOfBoundsException, though.)
Because that approach can be a bit long-winded, Kotlin has some other tools that can be better in particular situations.  I don't think any are appropriate here, but I'll mention some for completeness:
One of those is the safe-call operator ?. given in the error message and the earlier answer.  This makes the call only if the value is not null; otherwise, it returns the null directly.  That can be really useful, but it's not a simple answer in this case, as your comment shows: although it avoids trying to split() the null, you then fail to deconstruct it into the three values a, b, and c.  (After all, null is not an array.)
If you wanted to substitute default values for a, b, and c if there was no input, you could use the safe-call operator in conjunction with the elvis operator ?:.  That returns the left-hand side if it's not null, else the right-hand side.  So you could do e.g.:
val (a, b, c) = readLine()?.split(' ')
?: arrayOf("defA", "defB", "defC")
println("Values are $a, $b, and $c.")
In this case, if readLine() returns a string, split() would be called on it; or if not, it would use the hard-coded array instead.
Note that this still isn't a complete solution, as it won't cope if you enter a line with less than two spaces.  (So you'd still need to catch the IndexOutOfBoundsException, or check for that case explicitly.)
(Perhaps the shortest solution overall would be to leave the !! intact, and change the catch block to catch Exception, so it would catch the KotlinNullPointerException along with the IndexOutOfBoundsException.  I'm not recommending that, as it's ugly: it's not clear to anyone reading the code what could happen and what exceptions you're intending to catch — and it could hide other problems in the code if they also resulted in exceptions.)

Related

Kotlin "let{}" Doesn't Provide Smart Cast

Just learned Kotlin Nullable type and let{} function which replaces the if (xx != null) {} operation.
But one thing I am confused is that, we all know and I Think the Complier Should Know that when we use let{}, the variable/object who is calling this function is possiblly null, however the complier still requires me to add the safe call operator "?" after the variable name instead of providing Smart Cast like it does in if (xx != null) {}. Why?
My piece of code:
fun main() {
var number1: Int? = null
//val number2 = number1.let { it + 1 } ?: 10 //doesn't work, not quite "smart"
val number2 = number1?.let { it + 1 } ?: 10 //works, must have "?"
println(number1)
println(number2)
}
You've already got answers in the comments, but just to explain the ? thing...
Kotlin lets you make null-safe calls on nullable variables and properties, by adding ? before the call. You can chain this too, by doing
nullableObject?.someProperty?.someFunction()
which evaluates nullableObject, and if it's non-null it evaluates the next bit, otherwise the whole expression evaluates to null. If any part of the chain evaluates as null, the whole expression returns null.
So it has this short-circuiting effect, and you can use the elvis "if null" operator to create a default value if you can't evaluate the whole chain to a non-null result:
nullableObject?.nullableProperty?.someFunction() ?: defaultAction()
and once you introduce the null check in the chain, you have to add it for every call after that - it's basically propagating either the result of the previous bit, or the null it resolved to, so there's a null check at each step
The let block is just a scope function - you use it on a value, so you can run some code either using that value as a parameter or a receiver (a variable or this basically). It also has the side effect of creating a new temporary local variable holding that value, so if the original is a var it doesn't matter if that value changes, because your let code isn't referring to that variable anymore.
So it's useful for doing null checks one time, without worrying the underlying value could become null while you're doing stuff with it:
nullableVar?.let { it.definitelyIsNotNull() }
and the compiler will recognise that and smart cast it to a non-null type. An if (nullableVar != null) check can't guarantee that nullableVar won't be null by the time the next line is executed.

Instantiated class in Kotlin still possibly null. Why?

Question is simple:
In Kotlin, when I instantiate a fragments arguments with a Bundle(), the system still needs the arguments object to be reassured with !!. The arguments should be definitely not null by now, right? So why is that needed?
Here is the code:
private fun openPinCodeFragment(mode: PinView.Mode) {
currentFragment = PinCodeFragment()
currentFragment?.run {
arguments = Bundle()
arguments!!.putSerializable(MODE, mode)
}
openFragment(currentFragment)
}
If I remove the !! then:
You're setting the value of a variable which was defined outside of this scope (the declaration of arguments is not visible in your code).
No matter what you assign, it could have been changed by the time code execution reaches the next line to a null value by another Thread, that's why you have to use the !! here. I'd suggest defining arguments either in local scope with val or making it non-nullable in its definition.
This happens because arguments is of Bundle? type, this means that it can be either Bundle or null.
Instead of using an if to check whether it is null, like you would to in Java, the operators !! and ? were introduced.
For example if you want your code to be correct without using !! you could add:
if (arguments != null) {
arguments.putSerializable(MODE, mode)
}
Using these operators you have the following flexibility:
!! - you tell the compiler that the value cannot be null, it will throw error otherwise;
? - you don't care that much, if it is not null then it will access method and might return result, otherwise the result of such call is null and no action is made.

What is the difference between not-null checks in Kotlin?

There are some ways to fulfill a null-checking in Kotlin:
1.
if(myVar != null) {
foo(myVar)
}
2.
myVar?.let {
foo(it)
}
3.
myVar?.run {
foo(this)
}
What are the difference between these ways?
Are there any reasons (performance, best practice, code style etc.) why I should prefer on way over the other?
!! is to tell the compiler that I am sure the value of the variable is not null, and if it is null throw a null pointer exception (NPE) where as ?. is to tell the compiler that I am not sure if the value of the variable is null or not, if it is null do not throw any null pointer.
Another way of using a nullable property is safe call operator ?.
This calls the method if the property is not null or returns null if that property is null without throwing an NPE (null pointer exception).
nullableVariable?.someMethodCall()
All three code are behave same null check in operation-wise.
?. is used for chain operations.
bob?.department?.head?.name // if any of the properties in it is null it returns null
To perform a chain operation only for non-null values, you can use the safe call operator together with let
myVar?.let {
foo(it)
}
the above code is good for code style and performance
more details refer Null Safety
The ways 2 and 3 are more idiomatic for Kotlin. Both functions are quite similar. There is little difference with argument passing.
For example, we have a nullable variable:
var canBeNull: String? = null
When you working with T.run you work with extension function calling and you pass this in the closure.
canBeNull?.run {
println(length) // `this` could be omitted
}
When you call T.let you can use it like lambda argument it.
canBeNull?.let {
myString -> println(myString.length) // You could convert `it` to some other name
}
A good article about Kotlin standard functions.
All three are roughly equivalent.
The if case is more like most other languages, and so many developers may find it easier to read.
However, one difference is that the if case will read the value of myVar twice: once for the check, and again when passing it to foo(). That makes a difference, because if myVar is a property (i.e. something that could potentially be changed by another thread), then the compiler will warn that it could have been set to null after the check. If that's a problem (e.g. because foo() expects a non-null parameter), then you'll need to use one of the other cases.
For that reason, the let case has become fairly common practice in Kotlin. (The run case does just about the same thing, but for some reason isn't as popular for this sort of thing. I don't know why.)
Another way around it is to assign myVar to a temporary value, test that, and then use that. That's also more like other languages, but it's more verbose; many people prefer the conciseness of the let case — especially when myVar is actually a complicated expression.
The examples in your question don't show the true reason to decide.
First of all, since you're not using the return value of foo, you should use neither let nor run. Your choice is between also and apply.
Second, since you already have the result you want to null-check in a variable, the difference fades. This is a better motivating example:
complexCall(calculateArg1(), calculateArg2())?.also {
results.add(it)
}
as opposed to
val result = complexCall(calculateArg1(), calculateArg2())
if (result != null) {
results.add(result)
}
The second example declares an identifier, result, which is now available to the rest of the lexical scope, even though you're done with it in just one line.
The first example, on the other hand, keeps everything self-contained and when you go on reading the rest of the code, you are 100% confident that you don't have to keep in mind the meaning of result.
Kotlin have new features with NullPoint-Exception as Compare to Java.
Basically When we do Coding in Java , then we have to Check with !! in every Flied.
But in Kotlin, it is Easy way to Implement First
as Like,
Suppose, in Kotlin
var response:Json?=Null
response:Json?.let {
this part will handle automatic if response is Not Null....then this Block start Executing }?.run {
This is Nullable But, where we Can put Warring } So, I am Suggest you Guys to Start Work in Kotlin with this Features Provided by Kotlin.
(Flied)?.let { Not Null Value Comes Under }?.run{ Null Value Code }
This will Handle to NullPoint Exception or Protect You App for Crash
What you want to achieve
What you want to achieve is that the Kotlin compiler does a smart cast on the variable you are working with.
In all of your three examples, the compiler can do that.
Example:
if(myVar != null) {
foo(myVar) // smart cast: the compiler knows, that myVar can never be null here
}
The choice
Which one of the options to use, is really a matter of style. What you should not do is mix it up to often. Use one and stick to it.
You don't need to worry about performance since let and run are inlined (see inline function). This means that their code (body) is copied to the call site at compile time so there is no runtime overhead.

When working with Java libraries in Kotlin, is it more idiomatic to use ? or !! on method return values?

I'm new to Kotlin and there's a common pattern that I'm not sure how to deal with most correctly. Take this code, for example, which doesn't compile:
git_repo?.add().addFilepattern()
add() is a call in the JGit library which is purely Java, so its return type is AddCommand!.
I have two options:
git_repo?.add()!!.addFilepattern("test.txt")
and
git_repo?.add()?.addFilepattern("test.txt")
Both work fine and given that
I don't know the intricacies of the library implementation,
the documentation of the JGit library doesn't specify whether add() can return null, and
within this context I'd typically expect add() to not return a null
Which version is more idiomatically correct to write in Kotlin? It seems that this would be a fairly common issue to deal with since basically every non-Kotlin library would introduce this issue.
I would use the ?. safe operator and then put your own exception at the end after an ?: Elvis operator. This way you get a message that is meaningful. Using just !! isn't a very helpful message to someone down the road who has no idea what the intricacies were either.
val cmd = gitRepo.add()?.addFilepattern("test.txt") ?: throw IllegalStateException("assert: gitRepo.add() returned an unexpected null")
cmd.doSomething() // never is null guaranteed
If the value is every null you will have a custom error.
assert: gitRepo.add() returned an unexpected null
And after this line, you will not have to null check because the result of the expression is guaranteed never to be null.
If you inspect the code of the other library and ensure it would never ever be null no matter what, then a !! is appropriate. But if not sure, do one better with the custom message.
Note I dropped the first ?. from your example because I'm assuming git_repo itself is not nullable. Plus I renamed it not to have an underscore which isn't normal Kotlin naming convention.
If you are sure that git_repo will always return a value!! is fine in that case.
It is ugly but !! will always be there when you use Java libraries, and you can't avoid it.
The only reason i would use git_repo?.add()?.addFilepattern("test.txt"), would be if you are returning a value, and you want the value to be nullable so that your calling method can handle the nullable.
fun nullableMethod(): string? {
return git_repo?.add()?.addFilepattern("test.txt")
}
fun callingMethod() {
if(this.nullableMethod() != null) {
}
//Else
}
If you are guaranteed it is never going to null, use !!

Is `a?.let{} ?: run{}` idiomatic in Kotlin?

I saw the following comment in a S.O. post, and I'm intrigued:
why don't you use if for null checks? a?.let{} ?: run{} is only appropriate in rare cases, otherwise it is not idiomatic – voddan May 15 '16 at 7:29 best way to null check in kotlin?
Why is that construct "only appropriate in rare cases"?
The lead engineer for Kotlin says,
run allows you to use multiple statements on the right side of an elvis operator https://stackoverflow.com/a/51241983/6656019
although I admit that's not actually endorsing it as idiomatic. Both of these posts seem to be from very well respected S.O. Kotlin contributors.
The post that inspired the original comment mentions that the let part of the expression is important if a is mutable. In that case, you'll need a?.let{} ?: run{} instead of if{} else {}.
I find I like the "let Elvis run" construct. Should I avoid it in most cases?
Thanks for any insight.
It's dangerous to conflate foo?.let { bar(it) } ?: baz() with if (foo != null) bar(foo) else baz().
Say you have a function: fun computeElements(): List<Int>? = emptyList()
Consider this code:
val maxElement = computeElements()?.let { it.max() } ?: return
println("Max element was $maxElement")
Compared to:
val list: List<Int>? = computeElements()
val maxElement = if (list != null) list.max() else return
println("Max element was $maxElement")
You may think these are two equivalent forms. However, if you run both, you'll see that the former does not print anything to stdout!
This is because it.max() returns null for an empty list (because there is no max element), which causes the right-hand side of the Elvis expression to be evaluated, and so the function returns early.
In short, ?.let { ... } ?: ... allows both branches of the "if-else" to be evaluated, which is dangerous. Aside from this form not being readable (if-else is universally understood, while let-run is not), subtle bugs can occur.
In that case, you'll need a?.let{} ?: run{} instead of if{} else {}
No, you can omit the run part of run { statement } and use a?.let{} ?: statement.
Should I avoid it in most cases?
You should use it when you need it. E.g. when you want to run multiple statements in that scenario. It is pointed out that that is a rare scenario. Often you will see just a single statement on the right hand side of an elvis operator.
And of course don't use it when you don't need it. Keep the code simple.