Why can’t I add null in the list of model data arrays in Kotlin language?
adapterPaging!!.setOnLoadMoreListener {
var customersModels: List<CustomersModel> = ArrayList()
customersModels.add(null)
}
Why can’t I add null in the list of model data arrays in Kotlin language?
adapterPaging!!.setOnLoadMoreListener {
var customersModels: List<CustomersModel> = ArrayList()
customersModels.add(null)
}
2
Answers
Your customersModel POJO class must contain a nullable data type. and also you have to declare list as follow :-
var customersModels: ArrayList<CustomersModel?> = ArrayList() CustomersModel must be Then you will add null values to the list.
Your problem(?) here is polymorphism. You’ve defined
customersModels
as aList
, which in Kotlin is explicitly immutable. You can’tadd
things to it.You’re assigning an
ArrayList
to that variable, which is an object that does have theadd
method. And anArrayList
is
aList
, so you can do that. Like how a pencil is a writing tool that’s erasable, if someone just needs something to write with, you can give them a pencil or a pen. All they’ve asked for is something that writes.But the variable you’re interacting with,
customersModels
, is explicitly a reference to a KotlinList
– a more restrictive subtype ofMutableList
*. It knows nothing about what that object actually is, just that it fits the immutableList
type. That type does not have anadd
method so you can’t call it. Same as how if you ask for a writing tool, you can’t assume you’ll be able to erase what you write.So you have three options here (let’s not get into reflection):
You can cast that variable to another type:
This is an unchecked cast – you’re telling the compiler "hey I know what this is, you don’t but you’re just gonna have to trust me on this one". This is unsafe, because there’s no protection, the compiler can’t do any checking and force you to handle potential problems. (Don’t do this)
A better approach is to actually check as you cast – there are two ways to do this in Kotlin:
This is good for things where you handle a more general type, but you might want to get specific and handle different member types in different ways. Especially common if you’re using sealed classes.
The last approach is to just use the appropriate type in the first place!
You’re creating a list you want to change – so that’s a
MutableList
, and that’s whatcustomersModels
should be. This kind of thing can be internal – you can expose that list as aList
rather than aMutableList
, so that other stuff that uses it sees it as a fixed, immutable list. If you’ve usedLiveData
you’ve probably seen this approach:myData
is literally pointing at thatMutableLiveData
object, but because its type is justLiveData
(the immutable kind) that means stuff that accesses that public variable see an object they can’t change. Really they could cast it toMutableLiveData
and mess with it, but it’s less a security feature and more of an organisational thing. Make it clear how stuff is meant to be used, how you interact with it, etc. If you want to update, go through a specific function, that kind of thing.So use
List
if it’s just a list that’s meant to be read, not written to. If it will/might be changed, use theMutableList
type. This makes it clearer about what’s going on.Also, generally you shouldn’t use explicit types like
ArrayList
– Kotlin has a bunch of functions to generateList
s andMutableList
s, which makes it easier to reason about what you’re doing and why:Notice I’m not specifying the type next to the variable, it’s getting inferred by the function I’m using. So there’s no "treat this mutable list as an immutable one" going on (unless you need to do that for a specific reason!)