List can not add null,but Queue can add null value.why is this?
fun main() {
val list = mutableListOf<Int>()
// can not do it
list.add(null)
val queue: Queue<Int> = LinkedList()
// no problem
queue.add(null)
}
CodePudding user response:
TL/DR;
Java = can be null in most cases
kotlin = can define parameters as nullable or not nullable.
Thanks to @hotkey: More can be read here Kotlin Null-safety and platform types
The Queue
object comes from the package java.util.Queue<T>
(or your concrete class LinkedList
from java.util.LinkedList
). All java classes can get nullable values within kotlin.
This does not affect parameters that are annotated with @Nullable
.
The MutableList
class is a class from the kotlin.collections
and therefore defines explicit non nullable or nullable parameters/values.
A bit more detailed anwer:
The kotlin compiler has to allow nullable values because it does not know if a value can not be null in java. This is not the case if the parameter/value has been annotated with @NotNullable
.
Kotlin source code that you have compiled will be java bytecode. All that kotlin does is that is internally wrapps not nullable data types with statements to check is a particular value is null. If so it will throw an exception like java does.
If you for example implement an interface compiled from java using the Intellij IDEA, you will get parameters that are marked as nullable.
Example: Creating an implementation of javax.servlet.Filter
will result in the following generated source code:
class MyFilter : Filter {
override fun doFilter(p0: ServletRequest?, p1: ServletResponse?, p2: FilterChain?) {
TODO("Not yet implemented")
}
}
The interface however does not have any metadata about its function parameters. Kotlin has to concider a nulalble datatype.
Hope this helps you :)
CodePudding user response:
Another answer explains nullability from Kotlin's point of view — and that's the most important thing here.
But it's probably also worth mentioning that even at the underlying Java level, some collection classes support nulls, while others don't. They don't express this programmatically through the type system in the way that Kotlin does, but their documentation should say.
Some examples:
ArrayList
andLinkedList
can store null values.ConcurrentLinkedDeque
can't.HashSet
can store a null value.TreeSet
can store a null only if created with a comparator that handles nulls. (This means aTreeSet
with no comparator cannot store a null, as null has no natural ordering.)HashMap
can store null values and a null key.EnumMap
supports null values but not a null key.TreeMap
supports null values, but supports a null key only if it's using a comparator that does.ConcurrentHashMap
supports neither.
Many of these classes are commonly used in Kotlin too (either explicitly, or disguised as implementations of one of Kotlin's mapped types). If the Kotlin compiler can tell whether the collection can handle nulls, it will usually make the type parameters nullable or non-nullable accordingly — but it cannot always do so (especially for classes such as TreeSet
which can't tell until runtime), so you should never assume. Check the class's documentation if there's any doubt.