Basics
kotlin中一切皆對(duì)象凯肋,基本數(shù)據(jù)類(lèi)型會(huì)自動(dòng)裝箱成對(duì)象
基本數(shù)據(jù)類(lèi)型位寬與java一致
數(shù)組處理
java中基本數(shù)據(jù)類(lèi)型的數(shù)組用于避免封箱開(kāi)箱的操作躯枢,在kotlin中每一個(gè)java基本類(lèi)型的數(shù)組都有與其對(duì)應(yīng)的類(lèi)型IntArray DoubleArray....
它們不是Array類(lèi)掰担,而是被編譯成java的原生數(shù)組碟摆,來(lái)獲得最好的性能
其for-each 及 in check也不會(huì)帶來(lái)額外的開(kāi)銷(xiāo)(都轉(zhuǎn)換成java基本類(lèi)型操作)
如果java定義變長(zhǎng)基本類(lèi)型時(shí)孕荠,kotlin需傳遞類(lèi)似*IntArray給java
kotlin中無(wú)受檢異常
也就是說(shuō)预厌,編譯器不會(huì)強(qiáng)制你去捕捉任何異常
位操作
shl 類(lèi)似 <<
shr >>
ushr >>>
and &
or |
xor ^
inv ~
布爾運(yùn)算
布爾值的相關(guān)運(yùn)算與java類(lèi)似 || && 阿迈!
Array
//Array支持lambda參數(shù)的構(gòu)造函數(shù)
var a:Array<Int> = Array(2, {it->it*2});
String
支持字符串模板,原生字符串(like python)
Import
支持import as
Visibility Control
- private 當(dāng)前類(lèi)可見(jiàn)
- protected private + 繼承類(lèi)可見(jiàn)
- internal 同一模塊可見(jiàn)(模塊一般指intellij中的一個(gè)module)
- public 全部可見(jiàn)
Class and Objects
Constructor
class Person private constructor(name:String) {
// 基礎(chǔ)構(gòu)造函數(shù)不能放初始化代碼轧叽,如需苗沧,放init中
init {
var s = name.length
}
consturtor(parent:Person) {
// 如果有基礎(chǔ)構(gòu)造函數(shù),必須調(diào)用
this(parent.name)
}
}
// 如果不聲明任何構(gòu)造函數(shù)炭晒,會(huì)自動(dòng)獲得一個(gè)(類(lèi)似java)
Inheritance
open class Derived(p:Int):Base(p) { // 繼承
// 構(gòu)造函數(shù)必須顯示調(diào)用父類(lèi)
consturtor(ctx:Int):super(ctx) {
}
}
默認(rèn)情況下所有類(lèi)都是final的除非聲明為open,默認(rèn)所有的方法也是final的
支持多繼承
Object
object 用于聲明單例對(duì)象待逞,object聲明不能有構(gòu)造函數(shù)
object Instance {
val name = ""
}
Companion Objects
kotlin沒(méi)有靜態(tài)成員,但有伴隨對(duì)象,這樣類(lèi)似靜態(tài)成員的效果
open class A {
companion object {
val DEF_NAME = "DefaultName";
}
open fun test() {
}
}
Properties
var <propertyName>: <PropertyType> [= <property_initializer>] [<getter>]
[<setter>]
自定義setter的時(shí)候网严,如果需要對(duì)變量賦值识樱,可以使用Backing Field
eg :
open class Test {
var a : String? = null
set(value) {
if (!value.isNullOrBlank()) {
field = value // 此處如果使用a=value會(huì)導(dǎo)致遞歸調(diào)用
}
}
}
編譯期常量使用const 字段修飾
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
可使用lateinit關(guān)鍵字進(jìn)行懶加載(主要用于單元測(cè)試 setUp初始化)
如果定義一些屬性并且使用基本構(gòu)造函數(shù)初始化的話(huà)一種簡(jiǎn)練的寫(xiě)法是
class Test(var/val name:String)
Interface
接口類(lèi)似java8 可以有方法實(shí)現(xiàn),但其properties必須是abstract
Extensions
Extensions are resolved statically
擴(kuò)展方法是靜態(tài)解析的震束,也就是說(shuō)根據(jù)對(duì)象的聲明類(lèi)型而不是實(shí)際類(lèi)型來(lái)解析應(yīng)該調(diào)用哪個(gè)擴(kuò)展方法的
支持?jǐn)U展屬性,但必須通過(guò)get set訪(fǎng)問(wèn)怜庸,無(wú)法直接初始化
伴隨對(duì)象也支持?jǐn)U展
class C {
fun D.foo() { // D的擴(kuò)展函數(shù)
toString() // calls D.toString()
this@C.toString() // calls C.toString()
}
Generics
由于kotlin也是jvm語(yǔ)言,因此無(wú)法規(guī)避java泛型相關(guān)問(wèn)題垢村,仍遵循 PECS (Producer-Extends, Consumer-Super),不過(guò)增加了in out關(guān)鍵字割疾,變成了 Consummer in, Producer out
對(duì)于java中<T extends String> 在kotlin中寫(xiě)成<T:String>,如果要extends多個(gè)接口可以使用where關(guān)鍵字
fun <T> cloneWhenGreater(list: List<T>, threshold: T):List<T>where T : Comparable,T : Cloneable {
return list.filter { it > threshold }.map { it.clone()
}
}
Nested Classes
聲明普通內(nèi)部類(lèi)需使用 inner關(guān)鍵字否則的話(huà)就類(lèi)似java的靜態(tài)內(nèi)部類(lèi)
枚舉類(lèi)聲明為 enum class XXX
Delegated Properties
代理屬性
代理屬性在被訪(fǎng)問(wèn)的時(shí)候會(huì)調(diào)用代理對(duì)象的相關(guān)方法
object Instance {
var age:String by Delegate()
}
class Delegate {
operator fun getValue(any: Instance, property: KProperty<*>): String {
return any.age
}
operator fun setValue(instance: Instance, property: KProperty<*>, s: String) {
print("you set $instance's age = $s")
}
}