(Turn) [Kotlin] Null Safety

Reprinted from: http://blog.csdn.net/hp910315/article/details/50790681

 

One of the biggest differences between Kotlin and Java is that it strives to eliminate the dangers posed by null references. In Java, if we try to access a member of a null reference may result in the occurrence of NullPointerException (NPE). This problem is solved in Kotlin language, let's see how it is done.

In Kotlin, the type system distinguishes between nullable types and non-nullable types. For example, String is a non-nullable type and String? is a nullable type. If a non-nullable type is assigned null, it will not compile.

var a: String = "abc"
a = null // compilation error

var b: String? = "abc"
b = null // ok

 

 For non-nullable types, you can directly call its member variables or functions, but for nullable types, directly calling member variables or functions will fail to compile, which is equivalent to solving the restrictions directly at the syntax level.

Then the problem comes, because the nullable type will not compile when calling member variables or functions, but the nullable type can only be a null reference or not, and the compiler will do it all directly. Otherwise, if a nullable type itself It is not empty, we want to call its member variables or functions, but the compilation fails, which seems to be illogical.

E.g:

var a: String? = "abc"
val l = a.length  //compilation error

 The above code is logically no problem, but the compilation fails because String is a controllable type, and the compiler does not let it directly call member variables or functions. For possible types, if you want to call its member variables or functions, you must judge. Only, otherwise the compiler will not pass. This is how Kotlin solves null pointer exceptions. It will require programmers to avoid null pointer exceptions to the greatest extent possible.

var b: String? = "abc"
val l = if (b != null) b.length else -1

 There is no problem with the above code, because we have done the check, so the compiler allows to call the member variable of the nullable reference b.

For nullable references, if we want to call its member variables or functions, we must first check, otherwise the compiler will report an error.

E.g:

if (b != null && b.length > 0)
  print("String of length ${b.length}")
else
  print("Empty string")

 For this kind of restriction, there are good and bad, it feels a little rigid and a little troublesome. If you use a non-null reference, you must ensure that it is not null. This is acceptable. Use a nullable reference, and you have to check every time, which is very troublesome. , Haha, the designers of the language certainly wouldn't be so embarrassing. For simple use, there is a safe way to call nullable references, use ?. to call.

var b: String? = "abc"
b?.length  // ok

 In this way, you don't need to check, someone did it for you, if b is a null reference, return null directly, otherwise, return b.length. Keep it simple!

The specificity of the Kotlin language is simplicity. Everyone should pay attention to the fact that the above statements do not have semicolons. This is absolutely impossible in Java, but in Kotlin, you are so capricious. Do you remember the ternary operator in Java, there is a similar one in Kotlin.

val l: Int = if (b != null) b.length else -1
//Equivalent to
val l = b?.length ?: -1

 Returns -1 if b is null, otherwise returns b.length.

Calling of nullable references, there is a third aspect below to call its member functions and variables.

var b: String? = "abc"
val l = b!!.length()

 Its return value has two possibilities, if b is not null, return b.length(), otherwise, throw a null pointer exception, if b is null, you do not want to return null, but throw a null pointer exception, you can use it.

下面总结一下: 
1、Kotlin有两种类型:一个是非空引用类型,一个是可空引用类型。 
2、对于可空引用,如果希望调用它的成员变量或者成员函数,直接调用会出现编译错误,有三种方法可以调用: 
(1)在调用前,需要先检查,因为可能为null 
(2)使用b?.length的形式调用,如果b为null,返回null,否则返回b.length 
(3)使用b!!.length()的形式调用,如果b为null,抛出空指针异常,否则返回b.length

另外,我们知道类型转换可能产生ClassCastException异常,例如:

var a: Long = 1
val aInt: Int? = a as Int  // java.lang.ClassCastException

 那么如何避免这个异常呢?改成下面形式就可以了。

var a: Long = 1
val aInt: Int? = a as? Int

 上面这种方法就是安全类型转换,如果类型转换不成功,就会返回null,而不是抛出ClassCastException异常。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326053577&siteId=291194637