This article has been written before, deleted some nonsense, corrected some mistakes, get under the typesetting, recently started serializing this series, the structure of the article: extract points (convenient review) + general operation + source code level to explore the implementation principle, part of the content extracted from: “Kotlin practical guide”, interested in can subscribe a wave ~
0x1
- In Kotlin, NPE is avoided through “non-null type” and “nullable type”.
- The null operator ‘? ‘, the safe call operator ‘?. ‘, the non-null assertion operator ‘!! ‘ ‘;
- The Elvis operator “?: “returns it if it is not null, otherwise it returns another value;
- Safe type conversion “‘ as? ‘”
- ? .let{}
- Not absolute null-pointer safety: The Kotlin call returns empty Java code;
- The implementation principle of Kotlin’s space security:
0x2, Null safety usage in Kotlin
NullPointerException(NPE) a NullPointerException(NPE) thrown at runtime when a method that references an empty object.
Common circumventions in Java are:
Nulls the object before it is used: if (obj! = null)
Multi-layer space judgment is not very aesthetically pleasing, whereas Kotlin is “space safe” :
Null is handled at compile time
Space security is not unique to Kotlin, but is also available in many other programming languages. Here is a brief description of Kotlin’s use of space security.
① Non-null types and nullable types
Kotlin uses non-null type and nullable type to avoid NPE. Non-null type cannot be set to Null:
Nullable types can be set to Null values followed by the nullable operator (?). The code example is as follows:
A nullable type that directly accesses its properties or methods will return an error:
You can safely call the operator (? .). Or non-empty assertion operators (!!) The code example is as follows:
The running results are as follows:
② Elvis operator (? 🙂
Shorthand for the trinary conditional operator: return it if it is not empty, otherwise return another value. A code example is as follows:
③ Secure type conversion
In Kotlin, you can use the AS keyword for type conversions instead of as? Represents a conversion of a security type. If the parameter is null or non-string, an exception may be raised. If the parameter is null or non-string, an exception may be raised. , will not be converted if the parameter is abnormal. The code example is as follows:
The running results are as follows:
(4)? .let{}
The let function can be used to manipulate variables in the same scope (the code is more elegant) :
tvTitle.let {
it.text = "Title"
it.textSize = 18.0f
it.gravity = Gravity.LEFT or Gravity.CENTER
it.setOnClickListener {}
}
Copy the code
It can also be used to null, as in the following code:
Test: set a value, but still error, add a non-null assertion:
There is also a more elegant way to write code, which is to use 2, the modified code is as follows:
The other? The.let{} traversal collection ignores null values and only performs operations on non-NULL values; In addition, you can filter out non-empty elements with the set operator function filterNotNull.
0x3 is not absolutely null pointer safe
As mentioned, there is no absolute null-pointer safety in Kotlin. The most common method is to call Java code in Kotlin, as in the following example:
//Java
public class Test {
public static String getMsg() {
return null;
}
}
//Kotlin
fun main(a) {
println(Test.getMsg().length)
}
Copy the code
Error immediately after run:
Null security does break when you interoperate with Java code, but it’s easy to get around this. Add? An example is as follows:
fun main(a) {
println(Test.getMsg()? .length)
}
Copy the code
The running results are as follows:
Tips: This can also be done with @notnull annotations for Java code
0x4. How does Kotlin implement space security
Next, to explore how Kotlin implements empty safety, write a simple code:
fun test_1(str: String) = str.length
fun test_2(str: String?).= str? .length
fun test_3(str: String?).= str!! .length
fun test_4(str: Any?). { str as String }
fun test_5(str: Any?). { str as? String }
Copy the code
Then go to Tools -> Kotlin -> Show Kotlin Bytecode to generate the Bytecode:
The generated Java code looks like this:
The next wave is test_1, with an @notnull annotation, followed by:
Intrinsics.checkParameterIsNotNull(str, "str");
Copy the code
Intrinsics is an internal Kotlin class that addresses the checkParameterIsNotNull function:
To:
All right, so it’s essentially nulling the argument, and throwing an exception if the argument is null. Test_2 checks whether it is null. If not, call the corresponding method. Otherwise, return null. Test_3 is used to determine whether it is null. If it is null, it throws an Npe exception.
Next comes test_4, which checks for null if null throws a type conversion exception, otherwise the rest of the code executes; Finally, test_5 creates a new object and passes it the value of the argument, then evaluates the type. If it is not of a specific type, the object is assigned null, and then the cast object is assigned to a new object.
To sum up, Kotlin’s approach to air safety is as follows:
- The @notnull annotation is added to the compiler for non-null types. The @nullable annotation is added for Nullable types.
- 2. Non-null types directly null parameters and throw an exception if they are null.
- Nullable type, if yes? . Null, execute subsequent code if not null, otherwise return NULL; If it is!!!!! If it is empty, an NPE exception is thrown.
- If the as operator is null, it will throw an exception directly. If the as operator is not null, it will execute the following operation. An error may be reported at runtime!
- 5, the as? Create a new variable, assign a parameter to it, determine if it is of a particular type, assign the value of this variable to null, and then assign the value of this variable to another new variable, with a note: as? Parameter may be empty after processing!! So call as? The converted object also needs to add the security call operator (? .).
Note :(the reason to use compiled Java code directly here is more intuitive.)
- @ NotNull annotations in the corresponding bytecode: @ Lorg/jetbrains/annotations/NotNull;
- @ Nullable annotations in the corresponding bytecode: @ Lorg/jetbrains/annotations/Nullable;
References:
- Is Kotlin’s air safety really safe?