preface
In the last article, I mainly explored Kotlin and found that it is obviously different from Java. In this article, we will focus on the Null and exception corresponding to Kotlin.
1. Null type
As shown in the figure
When we define variables, if we do not assign initial values, the compiler will directly prompt syntax errors! When you are ready to directly assign the initial value to null, you will be reminded of show uses of variable 'name'.
In fact, this is one of Kotlin's features. It is set to avoid non empty. After all, the type of variable should be determined according to the attribute value of the variable. If the attribute value is empty, it naturally does not know what type of variable it is.
That's the problem. What if I can determine the type of this variable, but its attribute value may be empty for logical reasons?
fun main() { var str:String?= null //You can't use val here //str="hello word" println("input: ${str?.capitalize()}") }
Of course, Kotlin will think of such a problem! So there is a new syntax var variable name: variable type? Used to define nullable variables.
Of course, since your variable may be null, in order to avoid reporting null pointer exceptions, Kotlin has also prepared a solution for us to make the variable null. The syntax is: nullable variable The corresponding attribute method means that when the nullable variable is empty, the following methods will be automatically ignored. Using java means
if(str==null){//return only when the variable is null return; } //When the corresponding length of str is 0, the following method will still be executed str.capitalize();
Although the following method can be run when the string length is 0, what if you want to have special treatment in this case?
1.1 let keyword
fun main{ val str: String? = ""?.let { //Returns true if the character sequence is not empty and contains some characters other than white space characters. if (it.isNotBlank()) { it.capitalize() } else{ //Logical processing that can be left blank here "abc" } } println(str) }
Look at the operation effect first
abc
From this running effect, if the string length is 0, the default specified string will be returned.
To use a grammar in Kotlin, you should not only be able to use it, but also know its principle and why it is written like this! Only in this way, when you face Kotlin's advanced API, you can still calmly interpret and use the corresponding API!
Now let's enter the let source code and see how it is implemented!
@kotlin.internal.InlineOnly public inline fun <T, R> T.let(block: (T) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block(this) }
For you who don't understand Kotlin, you may feel a little complicated at the first sight. But as long as you know how to split and parse it, you can easily understand:
- First, look at < T, R > after fun. You can understand it as declaring the corresponding generic type in java and declaring two
- Then look at t.let (block: (T) - > R): R. first ignore block: (T) - > R to get: T.let(): R. you can regard it as a let method in the t object, and the return value of the method is: R
- Here, combined with the above example "" let, because here. let is preceded by a string, so this T can be understood as a string type for the time being
- So t.let (block: (T) - > R): R becomes string.let (block: (string) - > R): R
- Then continue to look at block: (string) - > R, and this is still a method. The formal parameter is a string and the return value is R;
- Finally, when we look at the return block(this), we can see that the block method is called in the let, and the return value of the block method is regarded as the return value of the closure let!
Note: these 6 items must be analyzed thoroughly, which is related to whether you can learn kotlin well later! If you don't understand, you can leave a message and I will answer it in turn.
Combined with the above analysis, take a look at the following code.
fun main{ var content:Int="asd".let { println("current value Is: $it") 123 //It is confirmed externally that it is of int type, so the return value of non int type is written here, which will directly prompt the syntax error! } var content1:Double=123.let{ println("current value Is: $it") 1.2//It is confirmed externally that it is a Double type, so write the return value of non Double type here and directly prompt the syntax error! } var content3=1.256.let { println("current value Is: $it") "I am content3" //Any type of return value can be placed here } println(content3.javaClass.name) }
Operation effect
current value Is: asd current value Is: 123 current value Is: 1.256 java.lang.String
The variable types of content and content1 here are determined. Only the variable content3 is uncertain, but its type is determined by the return value type of let closure.
From here, we can fully understand that T and R in the let represent the corresponding user and the variable type of it in the closure, the return value type of the closure and the variable type of external receiving the closure variable.
1.2 !! Symbol
This is very simple, which means that if it is empty, it will run directly and report an error.
fun main{ var str:String?= null!!.capitalize() }
Operation effect
Exception in thread "main" kotlin.KotlinNullPointerException at KotlinStudy02Kt.main(KotlinStudy02.kt:36) at KotlinStudy02Kt.main(KotlinStudy02.kt)
Direct error reporting for operation effect.
1.3 orEmpty method
This method means that when the target is null, the null character with length 0 will be returned through this method.
fun main{ var str: String? = null.orEmpty() if (str!=null){ str=str.capitalize() }else{ println("str by Null") } str= str?.capitalize().plus(" is Great. length: ${str?.length}") println(str) val strWithSafe: String = str ?: "butterfly" println(strWithSafe.length) }
Operation effect
is Great. length: 0 20
1.4 three item expression
fun main{ var str: String? = null val strWithSafe: String = str ?: "butterfly" //Here, it is expressed in java as String strWithSafe=(str==null?"butterfly":str) println(strWithSafe) }
fun main{ var str: String? = null str = str?.let { it.capitalize() } ?: "butterfly" println(str) }
These are very simple. You can take them directly and see the operation effect
butterfly
2. Custom exception
fun main{ var number: Int? = null checkOperation1(number) } fun checkOperation1(number: Int?) { number ?: throw MyTestException() } class MyTestException : Exception("This is a custom exception") }
Operation effect
Exception in thread "main" MyTestException: This is a custom exception at KotlinStudy02Kt.checkOperation1(KotlinStudy02.kt:64) at KotlinStudy02Kt.main(KotlinStudy02.kt:58) at KotlinStudy02Kt.main(KotlinStudy02.kt)
Of course, you can use your own
var number: Int? = null number = checkNotNull(number, { "Illegal operation" })
Operation effect
Exception in thread "main" java.lang.IllegalStateException: Illegal operation at KotlinStudy02Kt.main(KotlinStudy02.kt:59) at KotlinStudy02Kt.main(KotlinStudy02.kt)
Conclusion
Well, I'm sure you have a certain understanding of the null handling, let keyword and custom exceptions corresponding to Kotlin. In the next article, we will focus on the string operations, number types and standard library functions corresponding to Kotlin.