每一個類型都有一個toXXX方法,將該類型轉成其他類型。
1.2、Boolean它有兩個值,true和false,運算方式和Java一樣有三種,||,&&,!
1.3、數組數組用Array類實現,和Java不同的地方在於,Array類有一個size屬性表示數組長度,還有get和set方法,但是也可以使用array[position]的方式獲取
1.4、CharKotlin中的Char類型不能作為數字使用,如果需要的話需要使用toInt方法轉換。
1.5、字符串字符串的用法和Java的差不多,這裡需要注意的一點是我們可以使用字符串模版,模版表達式以美元符號開頭,例如:
1val string= "i=$i"
2println(string)
函數定義必須使用fun關鍵字,參數格式為 參數: 類型,如果有返回值,那麼在函數的最後指明,例如:
1fun sum(a: Int, b: Int) :Int {
2 return a+b
3}
可變變量,可讀並且可寫
1var <標識符> : <類型> = <初始化值>
2
不可變常量,只能賦值一次(類似Java中的final)
常量與變量都可以沒有初始化值,但是在引用前必須初始化4、NULL檢查機制又名Kotlin的空安全,這是Kotlin獨有的,在對於聲明可空的參數,在使用時要進行判空處理,有兩種處理方式,欄位後面加上!!,這樣可以像Java那樣如果為空就報空指針異常,還有一種是欄位後加?,這樣可以不做處理返回null或者配合?:(相當於Java中的三元運算)做判空處理:
1
2var age: String? = "23"
3
4val ages = age!!.toInt()
5
6val ages1 = age?.toInt()
7
8val ages2 = age?.toInt() ?: -1
if和else的使用同Java一樣,但是Java中的switch替換成了when,它既可以當作表達式使用,也可以當作語句使用:
1val x=1
2when(x){
3 1 -> print("x==1") 第一個條件
4 2 -> print("x==2") 第二個條件
5 ....
6 else -> { //最終(相當於switch的default)
7 print("x==xxx")
8 }
9}
10
11或者還可以這樣用
12
13val y=1
14when(y){
15 1,2 -> print("y==1 || y==2") //多個分支有相同的處理方式時可以用逗號隔開統一處理
16 else{
17 print("x==xxx")
18 }
19}
while,do whie的使用方法和Java一樣,唯一變的是for循環:
1for (i in 1..5){
2 print(i)
3}
4
5
6
7if (i in 1..5){
8
9}
10if (i !in 1..5){
11
12}
13
14for (i in 5 downTo 1){
15 print(i)
16}
17
18
19for (i in 1..5 step 2){
20 print(i)
21}
22
23
24for (i in 1 until 5){
25 print(i)
26}
27
在java中,有通配符和邊界的概念比如Class,表示上界通配符,它代表T以及T的子類,上限是T;在kotlin中可以使用out來替代例如clazz: Class<out T>
in:同樣也有下屆通配符比如,它表示T以及T的超類,下限是T;在kotlin中可以使用in來代替例如clazz: Class<in T>
靜態類和靜態方法 object(全局):使用object修飾的類,同時會創建一個實例(類似Java中的單例模式),可以直接通過 類名.方法名或者類名.屬性名來直接調用該類中的方法或者屬性。
1object TestUtil{
2 fun test(str:String){
3 }
4}
需要注意的是,如果在Java中調用的話需要先訪問該類靜態的INSTANCE,如TestUtil.INSTANCE.test()
companion object(部分):在kotlin中,我們可以使用companion object{}來修飾方法:
1companion object {
2 fun start(context: Context) {
3 FRStartActivity.start(context, MainActivity::class.java)
4 }
5}
這樣這個方法就相當於java中的靜態方法,我們可以直接使用 類名.方法 名來進行調用。
構造方法構造方法分為主構造方法和次構造方法,主構造方法只能有一個,次構造方法可以有多個:
1class Test(context: Context, flag: Int, string: String) {
2
3 constructor(context: Context, flag: Int) : this(context, flag, "")
4
5 constructor(context: Context, string: String) : this(context, 0, string)
6}
主構造函數在類頭中申明,而次構造函數在類體中申明;
主構造函數沒有任何修飾符時可以省略constructor關鍵字,而次構造函數不能省略;
主構造函數不能包含任何的代碼,而次構造函數可以;
主構造函數的參數可以在類體中的屬性初始化代碼和初始化塊中使用,而次構造函數的參數不能;
主構造函數中可以直接申明並初始化屬性,而次構造函數不能直接申明屬性;
如果申明了主構造函數,那麼所有的次構造函數都必需直接或間接地委託給主構造函數;
非抽象類中如果沒有聲明任何構造函數,會生成一個不帶參數的主構造函數,而不會生成任何次構造函數。
常見的操作符講解 1、: 操作符1.1、聲明常量和變量的類型
1var count:Int=0
2val TAG:String="Main"
1.2、類的繼承
1
2
3class MainActivity : Activity(){
4}
1.3、使用Java類
1val intent=Intent(this,MainActivity::class.java)
?一般在某個對象或者方法後面添加,表示該對象或者方法可以為空。
1var name:String?=null
2
3fun name(str:String):Int?{
4}
5
6name?.length
該操作符也稱之為Elvis操作符,來看一下它的使用方法:
1val length = name?.length ?: -1
如果?:左側表達式非空,那麼就會返回其左邊表達式的結果,否則返回右邊的。
4、!! 操作符1val length=name!!.length
如果name為null,那麼會寶空指針異常,否則會返回name的長度,它與?的區別在於它不允許為空,為空就報空指針異常。
5、as 與 as? 操作符這兩個操作符都是用來類型轉換的,但是前者可能會出現類型轉換出錯,然後會報ClassCastException異常,後者當出現類型轉換的錯誤時會返回null。
1private lateinit var textView : TextView
2private var imageView : ImageView? = null
3
4textView = findViewById(R.id.xxx) as TextView
5imageView = findViewById(R.id.xxx) as? ImageView
這兩個個操作符的使用和Java中的instanceof一樣,用來判斷某個實例是否屬於某個類型
1if (textView is View){
2}
3if (imageView !is TextView){
4}
擴展函數數是指在一個類上增加一種新的行為,甚至我們沒有這個類代碼的訪問權限。換句話說,我們可以給某個類進行擴展,在不改變原來類的基礎上增加一些新的函數方便我們使用,比如:
1fun Context.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
2 Toast.makeText(this, message, duration).show()
3}
4
5fun String?.isEmpty() = this == null || length == 0
對於上述函數,Context和String是函數擴展的對象,也就是你要給誰增加函數;.表示擴展函數修飾符;toast和isEmpty為函數名。
內聯函數Java的方法執行需要壓棧出棧,如果一個方法被多次調用,那麼就需要多次的壓棧出棧,為了節省這個操作,提高一定的效率,在kotlin中使用內聯函數來拷貝你調用的方法,然後在你當前方法中使用。
下面列舉kotlin中常用的幾個函數,用法可以參考:Kotlin中let、also、with、apply函數
1.1、let函數let擴展函數的實際上是一個作用域函數,當你需要去定義一個變量在一個特定的作用域範圍內,let函數的是一個不錯的選擇;let函數另一個作用就是可以避免寫一些判斷null的操作。let函數是有返回值的,它的返回值為函數塊的最後一行或指定return表達式。
使用場景:需要去明確一個變量所處特定的作用域範圍內可以使用。
1@kotlin.internal.InlineOnly
2public inline fun <T, R> T.let(block: (T) -> R): R {
3 contract {
4 callsInPlace(block, InvocationKind.EXACTLY_ONCE)
5 }
6 return block(this)
7}
also函數和let基本一樣,不同的是also返回的是當前對象。
使用場景:和let一樣
1@kotlin.internal.InlineOnly
2@SinceKotlin("1.1")
3public inline fun <T> T.also(block: (T) -> Unit): T {
4 contract {
5 callsInPlace(block, InvocationKind.EXACTLY_ONCE)
6 }
7 block(this)
8 return this
9}
with函數與其他函數不同,他不是一個擴展函數,它是將某個對象作為函數的參數,在函數塊內可以通過 this 指代該對象。返回值為函數塊的最後一行或指定return表達式。
使用場景:適用於調用同一個類的多個方法時,可以省去類名重複,直接調用類的方法即可,經常用於Android中RecyclerView中onBinderViewHolder中,數據model的屬性映射到UI上。
1@kotlin.internal.InlineOnly
2public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
3 contract {
4 callsInPlace(block, InvocationKind.EXACTLY_ONCE)
5 }
6 return receiver.block()
7}
run函數實際上可以說是let和with兩個函數的結合體,run函數隻接收一個lambda函數為參數,以閉包形式返回,返回值為最後一行的值或者指定的return的表達式。
使用場景:適用於let,with函數任何場景
1@kotlin.internal.InlineOnly
2public inline fun <T, R> T.run(block: T.() -> R): R {
3 contract {
4 callsInPlace(block, InvocationKind.EXACTLY_ONCE)
5 }
6 return block()
7}
apply和run差不多,不同的是apply函數返回的是他傳入的對象
使用場景:apply一般用於一個對象實例初始化的時候,需要對對象中的屬性進行賦值。
1@kotlin.internal.InlineOnly
2public inline fun <T> T.apply(block: T.() -> Unit): T {
3 contract {
4 callsInPlace(block, InvocationKind.EXACTLY_ONCE)
5 }
6 block()
7 return this
8}
注意:上面這些函數它們還有一個共同的使用場景,就是可以用來判空