What's the difference between !! and ? in Kotlin?

后端 未结 6 1302
情深已故
情深已故 2020-12-04 14:15

I am new to Kotlin. I want to know the difference between this two !! and ? in below code.

Below, there are two snippets: the first uses

相关标签:
6条回答
  • 2020-12-04 14:33

    As it said in Kotlin reference, !! is an option for NPE-lovers :)

    a!!.length
    

    will return a non-null value of a.length or throw a NullPointerException if a is null:

    val a: String? = null
    print(a!!.length) // >>> NPE: trying to get length of null
    

    a?.length
    

    returns a.length if a is not null, and null otherwise:

    val a: String? = null
    print(a?.length) // >>> null is printed in the console
    

    To sum up:

    +------------+--------------------+---------------------+----------------------+
    | a: String? |           a.length |           a?.length |           a!!.length |
    +------------+--------------------+---------------------+----------------------+
    |      "cat" | Compile time error |                   3 |                    3 |
    |       null | Compile time error |                null | NullPointerException |
    +------------+--------------------+---------------------+----------------------+
    

    Might be useful: What is a NullPointerException?

    0 讨论(0)
  • 2020-12-04 14:34

    this is '!!' double-bang operator is always return not-null value and this is '?' safe call operator returns value if value is not null, and null otherwise

    This is unsafe nullable type (T?) conversion to a non-nullable type (T). It will throw NullPointerException if the value is null.

    It is documented here along with Kotlin means of null-safety.

    ref - hotkey

    0 讨论(0)
  • 2020-12-04 14:49

    SafeCall Operator(?):

    var a: String = "abc"
    a = null  //compile time error
    
    val b: String? = null
    val result = b?.length//returns null
    

    Assertion Operator(!!):

     val b: String? = "dd" //any value or null 
     val l = b!!.length 
    //this throws null pointer exception if b is null otherwise returns actual
    
    0 讨论(0)
  • 2020-12-04 14:50

    Safe Calls operator

    In Kotlin

    var a = x?.length;
    

    Equivalent code in Java

    int a = valueOfInt();
    
    int valueOfInt() {
        if (x != null) {
            return x;
        } else {
            return null;
        }
    }
    

    Side chain rule

    bob?.department?.head?.name
    

    it can be read as->

    If bob is not null give me the department ,

    if department is not null give me the head,

    if head is not null give me the name.

    If any of it is null, then it returns null

    ? before Data type

    If ? used before data type like:

    val b: String? = null
    

    it means you can assign null value to it otherwise null value can't be assigned to it.

    The !! Operator

    For those who like to have Null Pointer Exception (NPE) in their program.

    val l = b!!.length
    

    this will return a non-null value of b if b is not null OR throw an NPE if b is null

    0 讨论(0)
  • 2020-12-04 14:55
    In Addition to what Alexander said and as shown in the docs too, 
    

    the ?. safe call operator is very useful in chaining, something like this

    student?.department?.hod?.name
    

    if there is no student, returns null otherwise look for his department. If department doesn't exist returns null otherwise look for hod (head of department) and so on.

    If any one of student, department or hod is null then the result will be null.

    0 讨论(0)
  • 2020-12-04 14:56

    the precedence of operators !, ?., !! is ?. > !! > !.

    the !! operator will raising KotlinNullPointerException when operates on a null reference, for example:

    null!!;// raise NullPointerException
    

    the safe call ?. operator will return null when operates on a null reference, for example:

    (null as? String)?.length; // return null;
    

    the !! operator in your second approach maybe raise NullPointerException if the left side is null, for example:

    mCurrentDataset?.load(..)!!
        ^-------------^
               | 
    when mCurrentDataset== null || load() == null a NullPointerException raised.
    

    you can using the elvis operator ?: instead of the !! operator in your case, for example:

    !(mCurrentDataset?.load(..)?:false)
    
    0 讨论(0)
提交回复
热议问题