3

When I am converting Java code from a library to Kotlin I see if null checks in the Java code and wonder how best to convert this.

Do I still need the if null check in Kotlin because I cant control if Java will make the object null?

Lets say I have a CameraDevice which could come back null from Java

Should I define this like this..

private lateinit var mCameraDevice: CameraDevice

and then no null check is needed or like this..

private var mCameraDevice: CameraDevice? = null

and then keep the null check

if (mCameraDevice != null) { // do something }

Nullability in Kotlin confuses me because I feel like I shouldn't have to deal with the null and should use option one, but basically every library I use is Java so I have to deal with nulls and go with option two

2
  • 2
    Just because all types are technically nullable doesn't mean that they are in practice, at runtime. If your design guarantees that the mCameraDevice can't possibly be null (unless there is a bug that needs to be fixed anyway), then use CameraDevice. If null is a valid value for mCameraDevice, then use CameraDevice?. Whether CameraDevice is a Java class or a Kotlin class doesn't change anything, BTW. Commented Nov 8, 2017 at 7:52
  • You should use nullable types for Java inter-op parts unless the code or JavaDoc of the Java library states it is guaranteed not null. Commented Nov 8, 2017 at 9:16

4 Answers 4

2

If you're not sure, you should better use the nullable types, because it's always possible that the legacy Java code returnes null. This version is safest. If otherwise you know that null is impossible, use the non-nullable type.

As written in the docs:

Any reference in Java may be null, which makes Kotlin's requirements of strict null-safety impractical for objects coming from Java. Types of Java declarations are treated specially in Kotlin and called platform types. Null-checks are relaxed for such types, so that safety guarantees for them are the same as in Java.

If you work with Java returned values, which you think will never be null, are going to cause NullpointerExceptions at runtime if you work with them as not nullable types.

Java:

public class Nullable {

    public String get(){
        return null;
    }
}

Kotlin:

Nullable().get().length //-> NPE
Sign up to request clarification or add additional context in comments.

2 Comments

If I set something as can't be null in Java and then Java sets it to null does that just cause a NullPointerException?
Yes, that will happen
2
if (mCameraDevice != null) { // do something }

What are you going to do in the else case? If the answer is "throw an exception", just use a non-nullable type and Kotlin will effectively do it for you; otherwise a nullable type is reasonable.

Also, if mCameraDevice is a var, inside // do something Kotlin can't assume it's non-null: something could change it after the check! A common idiom is

mCameraDevice?.let { mCameraDevice -> // do something }

1 Comment

One thing I don't get with Kotlin's null safety is this lack of else scenario. if I do something like mCameraDevice? or mCameraDevice?.let I am basically saying do this is mCameraDevice is not equal to null but if it is null don't do ANYTHING at all. That to me seems like a really bad coding practice as the code would fail silently and the user would have no idea that something had failed. And using if else doesn't seem to work because Kotlin shows an error saying that it can't smart cast by this point because the mutable might have changed by this point!
1

try this mCameraDevice?.yourMethod()

It will perform your method if mCameraDevice is not null.

ref : https://kotlinlang.org/docs/reference/null-safety.html#safe-calls

Comments

0

lateinit is really meant for just what is sounds like, variable that you initialize late.

For example in android you don't have assess to the constructor for an activity, so lateinit comes in handy where you want to access a variable that you know is not null because you set its value in onCreate with out any null checks, ? 's or !! 's.

For example:

class MainActivity : AppCompatActivity() {

    private lateinit var field: EditText

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        field = findViewById<EditText>(R.id.field)
    }

    fun someOtherMethod() {
        println(field.text)
    }

}

Without lateinit you would need to declare field as an EditText? and then use all the null safety options that Kotlin provides.

In Java interop, if a library method can return a null, then you should just treat it like a Kotlin nullable, and access via save navigation someObject?.someMethod or in some other safe manner such as the let method.

someObject?.let { it.someMethod }  // as also pointed out by Alexey Romanov

So in your case since you specifically say Java may provide you with a null CameraDevice, you should definitely not use lateinit for this as it is not the intended purpose.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.