The difference between !! and ? in Kotlin

 ̄綄美尐妖づ 提交于 2019-12-20 08:32:49

问题


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

I am having below two snippet first having use of !! for mCurrentDataset and another having ? for same variable.

if(!mCurrentDataset!!.load(mDataSetString.get(mCurrentDataSelectionIndex), STORAGE_TYPE.STORAGE_APPRESOURCE))
{
    Log.d("MyActivity","Failed to load data.")
    return false
}

if(!mCurrentDataset?.load(mDataSetString.get(mCurrentDataSelectionIndex), STORAGE_TYPE.STORAGE_APPRESOURCE)!!)
{
    Log.d("MyActivity","Failed to load data.")
    return false
}

Thanks in advance.


回答1:


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?




回答2:


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)



回答3:


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




回答4:


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.




回答5:


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


来源:https://stackoverflow.com/questions/44536114/the-difference-between-and-in-kotlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!