Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nullable var with `?` vs. lateinit var

Tags:

android

kotlin

What is the best way to define global variables in a Kotlin/Android activity/fragment?

What are the different scenarios when you should use these 2 methods for defining a global variable:

var viewpager: CustomViewPager? = null 

or

lateinit var viewpager: CustomViewPager

?

If I use the former, I won't have to check for null in my code. For example if I used lateinit for the following:

viewpager = activity?.findViewById<CustomViewPager>(R.id.viewpager) then I would have to check for null.

like image 966
Zorgan Avatar asked Jul 21 '19 12:07

Zorgan


People also ask

Can Lateinit be NULLable?

lateinit is only for avoid null checks in future, that's why lateinit modifier is not allowed on properties of nullable types.

When should I use Lateinit?

lateinit means that variable must be initialised later. It should be initialized before accessing it. If you attempt accessing uninitialized lateinit variable UninitializedPropertyAccessException will be thrown. It's always better to avoid using nulls in your app.

What does Lateinit var mean?

The lateinit keyword allows you to avoid initializing a property when an object is constructed. If your property is referenced before being initialized, Kotlin throws an UninitializedPropertyAccessException , so be sure to initialize your property as soon as possible.


3 Answers

using lateinit, you are saying that you absolutely will make sure that an instance of that variable is created somewhere (otherwise, your application will throw an exception if a lateinit has not been initialized) and then that variable also will not be null throughout the rest of your project, compared to using null, it means that this object potentially could be null somewhere in your code for the rest of the project and you will have to deal with nullability throughout.

If you are positive that you are not going to make a variable null and you require an instance of it always, use lateinit

Ask yourself this question :

Am I 100% sure that I will be using an instance of this variable somewhere in this class ?

If the answer to that is Yes, you should probably be using lateinit, as lateinit forces you to create an instance of it.

If the answer is No, you should probably be using a nullable field instead.

Taken from here : https://www.kotlindevelopment.com/lateinit-kotlin/

The lateinit keyword stands for late initialization. Lateinit comes very handy when a non-null initializer cannot be supplied in the constructor, but the developer is certain that the variable will not be null when accessing it, thus avoiding null checks when referencing it later.

like image 142
a_local_nobody Avatar answered Oct 22 '22 02:10

a_local_nobody


i would recommend using the first method, it's better cause it eliminates app crashes if the code is trying to access the viewPager while it was not initialized, you can also use this in order to access the viewPager in the first method to make sure your app won't crash

viewPager?.let{"it"

}

this will create an instance of the viewPager if it was already initialized and use it as a val instead of a var, the instance is called "it" and u can rename it as anything by doing this after the first {

viewPager?.let{viewPager ->

}
like image 35
Mahmoud Omara Avatar answered Oct 22 '22 03:10

Mahmoud Omara


If you make sure that variable will never be null in any place of the code then use lateinit. Here you have to initialize it before using it (in your case you can initialize it inside onCreate(..). Make sure that the variable will never become null later ELSE a null pointer exception will be fired. In this way, you can directly use the variable without checking it if it's null or not. Also, you can detect if the variable has initialized or not using:

if (:: viewpager.isInitialized) { .... }

On the other hand, you should use the nullable option using ? In this case, you should check the variable before using it if it's null or not. you can use ?. for that. You also can combine that with let for example:

viewPager?.let {
 ....
}
like image 45
Mahmoud Avatar answered Oct 22 '22 02:10

Mahmoud