Kotlin筆記 和Java不同的寫法標記

扔物線老師的原文章_那些不是那么寫的
跟著走一遍,加深印象和理解

構造器

  • 需要加 constructor 標識
  • 沒有public修飾, 默認可見性就是公開的
class User {
    var name: String = ""
    constructor(name: String) {
        this.name = name
    }
}

init

  • 都在實例化時執(zhí)行滓技,并且執(zhí)行順序都在構造器之前
java 
public class User {
   ??
    {
        // 初始化代碼塊,先于下面的構造器執(zhí)行
    }
    public User() {
    }
}
???
class User {
    ??
    init {
        // 初始化代碼塊呻粹,先于下面的構造器執(zhí)行
    }
    constructor() {
    }
}

final

image.png
  • kotlin 中的 val 和 final類似
  • kotlin 函數參數默認是val類型, 所以參數錢不需要寫 val 關鍵字

val自定義getter

valfinal 有一點區(qū)別: 雖然val修飾的變量不能二次賦值, 但可以通過自定義變量的getter函數, 讓變量每次被訪問時,返回動態(tài)獲取的值

val size: Int
    get() { // ?? 每次獲取 size 值時都會執(zhí)行 items.size
        return items.size
    }

static property /function

  • 在 Kotlin 里秀又,靜態(tài)變量和靜態(tài)方法這兩個概念被去除了
    companion object
class Sample {
    ...
       ??
    companion object {
        val anotherString = "Another String"
    }
}

object (kotlin的單例)

  • Java 中的 Object在 Kotlin 中變成了 Any流济,和 Object作用一樣:作為所有類的基類萌壳。
  • object不是類, 在kotlin中是和calss一樣屬于關鍵字
  • object的意思: 創(chuàng)建一個類,并且創(chuàng)建一個這個類的對象,在代碼中使用這個對象,可以直接通過類名訪問,
  • 創(chuàng)建一個kotlin的單例, 只需要將class換成object
  • object 繼承和實現接口都可(簡單來講, 將class關鍵字的功能和單例合二為一)

和java相比不同點:

  • 和類的定義類似莉钙,但是把 class 換成了 object 嵌莉。
  • 不需要額外維護一個實例變量 sInstance进萄。
  • 不需要「保證實例只創(chuàng)建一次」的 getInstance() 方法。

匿名類

Java的寫法 ??

ViewPager.SimpleOnPageChangeListener listener = new ViewPager.SimpleOnPageChangeListener() {
    @Override // ??
    public void onPageSelected(int position) {
        // override
    }
};

Kotlin的寫法 ??

val listener = object: ViewPager.SimpleOnPageChangeListener() {
   override fun onPageSelected(position: Int) {
       // override
   }

}
Kotlin

  • 和java很相似, 只是將new換成了object
  • Java 中 new 用來創(chuàng)建一個匿名類的對象
  • Kotlin 中 object: 也可以用來創(chuàng)建匿名類的對象
  • 這里的 newobject:修飾的都是接口或者抽象類锐峭。

companion object

  • object修飾對象中的變量函數都是靜態(tài)的
    只想讓類中的一部分函數和變量是靜態(tài),寫法??
class A {
    object B {
        var c: Int = 0
    }
}

訪問可以直接 A.B.c

類中嵌套的對象可以用 companion 修飾

  • 當有 companion 修飾時中鼠,對象的名字也可以省略掉


    一個類中只能有一個伴生對象

top-level property / function 聲明

top-level declaration 頂層聲明」

  • 其實就是把屬性和函數的聲明不寫在 class 里面
package com.example.kotlinstudy

fun topTest(){
}

引用topTest()

  • 這樣寫的屬性和函數,不屬于任何class,直接屬于 package
  • 和靜態(tài)變量,靜態(tài)函數一樣是全局的,使用的時候可不寫類名
  • 相同命名的頂級函數, IDE會自動加上包前綴區(qū)分

object沿癞、companion objecttop-level 選擇對比

  • 如果想寫工具類的功能援雇,直接創(chuàng)建文件,寫 top-level「頂層」函數椎扬。
  • 如果需要繼承別的類或者實現接口惫搏,就用 object 或 companion object。

常 量

class Sample {
    companion object {
         ??                  // ??
        const val CONST_NUMBER = 1
    }
}

數組和集合

java寫法
String[] strs = {"a", "b", "c"};

Kotlin寫法
val strs: Array<String> = arrayOf("a", "b", "c")
//獲取: 
strs[0]
//修改: 
strs[1]="B"

kotlin中的數組是一個擁有泛型的類,創(chuàng)建函數也是泛型函數,和集合數據類型一樣
kotlin數組的工具函數
get() / set()
contains()
first()
find()

  • 不支持協(xié)變
    Kotlin 的數組編譯成字節(jié)碼時使用的仍然是 Java 的數組蚕涤,但在語言層面是泛型實現筐赔,這樣會失去協(xié)變 (covariance) 特性,就是子類數組對象不能賦值給父類的數組變量
// Kotlin: 
val strs: Array<String> = arrayOf("a", "b", "c")
val anys: Array<Any> = strs // compile-error: Type mismatch

//而這在 Java 中是可以的:
String[] strs = {"a", "b", "c"};
Object[] objs = strs; // success

集合

Kotlin 和 Java 一樣有三種集合類型:List揖铜、Set 和 Map

  • list 以固定順序存儲一組元素茴丰,元素可以重復。
  • Set 存儲一組互不相等的元素天吓,通常沒有固定順序贿肩。
  • Map存儲 鍵-值 對的數據集合,鍵互不相等龄寞,但不同的鍵可以對應相同的值尸曼。

list

//java 寫法
List<String> strList = new ArrayList<>();
strList.add("a");
//kotlin寫法
val strList = listOf("a", "b", "c")

Kotlin中的List支持協(xié)變,可把子類的list賦值給父類的list變量

val strs: List<String> =listOf("a", "b", "c")
val anys: List<Any> =strs //success

而這在java中是會報錯的

  • 對于協(xié)變的支持與否,List 和數組剛好反過來

和數組的區(qū)別

  • 這個問題在 Java 中就存在了萄焦,數組和 List 的功能類似,List 的功能更多一些,直覺上應該用 List 拂封。但數組也不是沒有優(yōu)勢茬射,基本類型 (int[]、float[]) 的數組不用自動裝箱冒签,性能好一點在抛。

  • 在 Kotlin 中也是同樣的道理,在一些性能需求比較苛刻的場景萧恕,并且元素類型是基本類型時刚梭,用數組好一點。不過這里要注意一點票唆,Kotlin 中要用專門的基本類型數組類 (IntArray FloatArray LongArray) 才可以免于裝箱朴读。也就是說元素不是基本類型時,相比 Array走趋,用 List 更方便些衅金。

Set

//java寫法
Set<String> strSet = new HashSet<>();
strSet.add("a");
//Kotlin寫法
val strSet = setOf("a", "b", "c")
  • 和 List 類似,Set 同樣具有 covariant(協(xié)變)特性簿煌。

Map

//java寫法
Map<String, Integer> map = new HashMap<>();
map.put("key1", 1);
//kotlin寫法
val map=mapOf("key1" to 1, "key2" to 2,"key3" to 3)

mapOf的每個參數表示一個鍵值對氮唯,to表示將「鍵」和「值」關聯,這個叫做「中綴表達式」

取值和修改

  • kotlin中的Map除了和 Java 一樣可以使用 get() 根據鍵獲取對應的值姨伟,還可以使用方括號的方式獲瘸土稹:
val value1 = map.get("key1")
val value2 = map["key2"]
  • 類似的,kotlin中也可以用方括號方式改變Map 鍵對應的值
val map = mutableMapOf("key1" to 1, "key2" to 2)
map.put("key1", 2)
map["key1"] = 2    
  • 你這里用到了「操作符重載」的知識,實現了和數組一樣的「Positional Access Operations」

可變集合/不可變集合

上面修改Map值的例子中夺荒,創(chuàng)建函數用的是 mutableMapOf() 而不是 mapOf()瞒渠,因為只有 mutableMapOf()創(chuàng)建的 Map 才可以修改。Kotlin 中集合分為兩種類型:
只讀的和可變的般堆。這里的只讀有兩層意思:

  • 集合的size不可變
  • 集合中的元素值不可變

以下是三種集合類型創(chuàng)建不可變和可變實例的例子:
listOf()創(chuàng)建不可變的 List在孝,mutableListOf()創(chuàng)建可變的 List
setOf()創(chuàng)建不可變的 Set淮摔,mutableSetOf()創(chuàng)建可變的 Set私沮。
mapOf()創(chuàng)建不可變的 MapmutableMapOf()創(chuàng)建可變的 Map和橙。
mutable(單詞意思可變的)前綴創(chuàng)建的函數都是可變的, 沒有mutable前綴都不可變, 但是可以通過toMutable*()系函數轉換成可變的集合

val strList = listOf("a", "b", "c")
strList.toMutableList() //轉換成可變
val strSet = setOf("a", "b", "c")
strSet.toMutableSet() //轉換成可變
val map = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 3)
map.toMutableMap() //轉換成可變
  • toMutable*() 返回的是一個新建的集合仔燕,原有的集合還是不可變的,所以只能對函數返回的集合修改魔招。

Sequence

kotlin引入的新的容器類型 Sequence ,和 Iterable 一樣用 來遍歷一組數據并可以對每個元素進行特定的處理

創(chuàng)建

1. 類似listOf(),使用一組元素創(chuàng)建
sequenceOf("a", "b", "c")
2. 使用Iterable創(chuàng)建
val list=listOf("a", "b", "c")
list.asSequence()
3. 使用 lambda 表達式創(chuàng)建
val sequence= generateSequence(0) {it +1}

可見性修飾符

kotlin的四種可見性修飾符

  • public:公開晰搀,可見性最大,哪里都可以引用办斑。
  • private:私有外恕,可見性最小杆逗,根據聲明位置不同可分為類中可見和文件中可見。
  • protected:保護鳞疲,相當于 private + 子類可見罪郊。
  • internal:內部,僅對 module 內可見尚洽。

相比 Java 少了一個 default「包內可見」修飾符悔橄,多了一個internal「module 內可見」修飾符。這一節(jié)結合例子講講 Kotlin 這四種可見性修飾符腺毫,以及在 Kotlin 和 Java 中的不同癣疟。

public

Kotlin 中如果不寫可見性修飾符,就表示公開潮酒,和 Java 中 public修飾符具有相同效果睛挚。在 Kotlin 中 public修飾符「可以加,但沒必要」澈灼。

@ hide

在 Android 的官方 sdk 中竞川,有一些方法只想對 sdk 內可見,不想開放給用戶使用(因為這些方法不太穩(wěn)定叁熔,在后續(xù)版本中很有可能會修改或刪掉)委乌。為了實現這個特性,會在方法的注釋中添加一個 Javadoc 方法 @hide荣回,用來限制客戶端訪問:

* @hide ??
*/
public void hideMethod() {
    ...
}

但這種限制不太嚴格遭贸,可以通過反射訪問到限制的方法。針對這個情況心软,Kotlin 引進了一個更為嚴格的可見性修飾符:internal

internal

internal 表示修飾的類壕吹、函數僅對 module 內可見,這里的 module 具體指的是一組共同編譯的 kotlin 文件删铃,常見的形式有:

  • Android Studio 里的 module
  • Maven project

internal在寫一個 library module 時非常有用耳贬,當需要創(chuàng)建一個函數僅開放給 module 內部使用,不想對 library 的使用者可見猎唁,這時就應該用 internal 可見性修飾符咒劲。

Java 的「包內可見」怎么沒了?

Java 的 default「包內可見」在 Kotlin 中被棄用掉了诫隅,Kotlin 中與它最接近的可見性修飾符是internal「module 內可見」腐魂。為什么會棄用掉包內可見呢?我覺得有這幾個原因:

  • Kotlin 鼓勵創(chuàng)建 top-level 函數和屬性逐纬,一個源碼文件可以包含多個類蛔屹,使得 Kotlin 的源碼結構更加扁平化,包結構不再像 Java 中那么重要豁生。
  • 為了代碼的解耦和可維護性兔毒,module 越來越多漫贞、越來越小,使得 internal 「module 內可見」已經可以滿足對于代碼封裝的需求育叁。

protected

  • Java 中 protected 表示包內可見 + 子類可見绕辖。
  • Kotlin 中 protected表示 private + 子類可見。

Kotlin 相比 Java protected的可見范圍收窄了擂红,原因是 Kotlin 中不再有「包內可見」的概念了,相比 Java 的可見性著眼于 package围小,Kotlin 更關心的是 module昵骤。

private

Java 中的 private表示類中可見,作為內部類時對外部類「可見」肯适。
Kotlin 中的 private 表示類中或所在文件內可見变秦,作為內部類時對外部類「不可見」。

private修飾的變量「類中可見」和 「文件中可見」:

class Sample {
    private val propertyInClass = 1 // ?? 僅 Sample 類中可見
}

private val propertyInFile = "A string." // ?? 范圍更大框舔,整個文件可見
private 修飾內部類的變量時蹦玫,在 Java 和 Kotlin 中的區(qū)別:
  • 在 Java 中,外部類可以訪問內部類的 private 變量:
//java代碼示例
public class Outter {
    public void method() {
        Inner inner = new Inner();
                            ??
        int result = inner.number * 2; // success
    }
    
    private class Inner {
        private int number = 0;
    }
}
  • 在 Kotlin 中刘绣,外部類不可以訪問內部類的 private 變量:
//kotlin示例代碼
class Outter {
    fun method() {
        val inner = Inner()
                            ??
        val result = inner.number * 2 // compile-error: Cannot access 'number': it is private in 'Inner'
    }
    
    class Inner {
        private val number = 1
    }
}
  • 可以修飾類和接口
  • Java 中一個文件只允許一個外部類樱溉,所以 class 和 interface 不允許設置為 private,因為聲明 private 后無法被外部使用纬凤,這樣就沒有意義了福贞。
  • Kotlin 允許同一個文件聲明多個 class 和 top-level 的函數和屬性,所以 Kotlin 中允許類和接口聲明為 private停士,因為同個文件中的其它成員可以訪問:
private class Sample {
    val number = 1
    fun method() {
        println("Sample method()")
    }
}
            // ?? 在同一個文件中挖帘,所以可以訪問
val sample = Sample()
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市恋技,隨后出現的幾起案子拇舀,更是在濱河造成了極大的恐慌,老刑警劉巖蜻底,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骄崩,死亡現場離奇詭異,居然都是意外死亡朱躺,警方通過查閱死者的電腦和手機刁赖,發(fā)現死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來长搀,“玉大人宇弛,你說我怎么就攤上這事≡辞耄” “怎么了枪芒?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵彻况,是天一觀的道長。 經常有香客問我舅踪,道長纽甘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任抽碌,我火速辦了婚禮悍赢,結果婚禮上,老公的妹妹穿的比我還像新娘货徙。我一直安慰自己左权,他們只是感情好,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布痴颊。 她就那樣靜靜地躺著赏迟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蠢棱。 梳的紋絲不亂的頭發(fā)上锌杀,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天,我揣著相機與錄音泻仙,去河邊找鬼糕再。 笑死,一個胖子當著我的面吹牛饰豺,可吹牛的內容都是我干的亿鲜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼冤吨,長吁一口氣:“原來是場噩夢啊……” “哼蒿柳!你這毒婦竟也來了?” 一聲冷哼從身側響起漩蟆,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤垒探,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后怠李,有當地人在樹林里發(fā)現了一具尸體圾叼,經...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年捺癞,在試婚紗的時候發(fā)現自己被綠了夷蚊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡髓介,死狀恐怖惕鼓,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情唐础,我是刑警寧澤箱歧,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布矾飞,位于F島的核電站,受9級特大地震影響呀邢,放射性物質發(fā)生泄漏洒沦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一价淌、第九天 我趴在偏房一處隱蔽的房頂上張望申眼。 院中可真熱鬧,春花似錦蝉衣、人聲如沸豺型。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至钓辆,卻和暖如春剪验,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背前联。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工功戚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人似嗤。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓啸臀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親烁落。 傳聞我的和親對象是個殘疾皇子乘粒,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內容

  • 3 Java與Kotlin的寫法比較 3.1 構造器、變量伤塌、常量和靜態(tài)數據 3.1.1 構造函數 java中的構造...
    安卓老菜鳥閱讀 629評論 0 0
  • 完成 Kotlin 中級部分的學習了灯萍,現在對其與 Java 的不同之處進行下總結,同時復習下 Kotlin 的知識...
    DylanXing閱讀 3,138評論 0 8
  • 1. 重點理解val的使用規(guī)則 引用1 如果說var代表了varible(變量)每聪,那么val可看成value(值)...
    leeeyou閱讀 516評論 0 0
  • Kotlin筆記 要理解Java與Kotlin的區(qū)別旦棉,就要從最根本的上來理解。Java是解釋型語言(邊解釋成二進制...
    FFFSnow閱讀 998評論 0 0
  • 類 構造函數 在Kotlin中一個類可以有一個主構造函數和一個或多個的次構造函數药薯,主構造函數是類頭的一部分 如果一...
    王小寶wy閱讀 571評論 0 0