kotlin基本常识处理
1. 基本数据处理
1.1 get和set的处理
格式上和 Java 有一些区别:
-
getter / setter 函数有了专门的关键字 get 和 set
-
getter / setter 函数位于 var 所声明的变量下面
-
setter 函数参数是 value
除此之外还多了一个叫 field 的东西。这个东西叫做「Backing Field」。这个 field 对编码的人不可见,但会自动应用于 getter 和 setter,因此它被命名为「Backing Field」。在 Kotlin 里,它相当于每一个 var 内部的一个变量。
class User { var name = "Mike" 👇 get() { return field + " nb" } 👇 👇 set(value) { field = "Cute " + value } }1.2 Constants in Kotlin
1.1.1 静态常量
- Companion object
Kotlin中没有static关键字,如果你想在类中声明静态方法或属性,就要把他们放在companion object(伴生对象)中。
class Constants { companion object { val FOO = "foo" } }
-
const val
使用条件
- 作为顶层属性、
companion object属性,或object属性 - 只可修饰String或原始类型
- 不能自定义getter
class Constants { companion object { const val FOO = "foo" } } // 静态常量
- JvmField
把上面const去掉,给FOO加上JvmField注解 生成的Java代码原文没给
class Constants { companion object { @JvmField val FOO = Foo() //Foo()是为了说明不限定于原始类型 } }
eg:
class Constants { companion object{ const val data = 5 } }1.1.2 Top-Level
如果一个类只是用来装载常量,那我们可以放心大胆地“丢弃这个类和companion object”,使用Kotlin的文件级属性(顶层属性) 直接在kt文件中
const val FOO = "foo"
生成对应的Java代码(或许就是你在使用Java时会写上的代码)
public final class ConstantsKt { @NotNull public static final String FOO = "foo"; }eg:
const val data = 51.3 NULL检查机制
Kotlin的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,有两种处理方式,字段后加!!像Java一样抛出空异常,另一种字段后加?可不做处理返回值为 null或配合?:做空判断处理
//类型后面加?表示可为空 var age: String? = "23" //抛出空指针异常 val ages = age!!.toInt() //不做处理返回 null val ages1 = age?.toInt() //age为空返回-1 val ages2 = age?.toInt() ?: -11.3.1 基本函数的使用
private fun dataTest(){ Log.d(TAG, "test the data:$data") var result = add(5,6) mText?.text = "$result" Log.d(TAG, "test the data:$result") } private fun add(a:Int,b:Int):Int{ return a+b } 对于当前的变量值尽量使用$来1.4 字符串模板
$ 表示一个变量名或者变量值
$varName 表示变量值
${varName.fun()} 表示变量的方法返回值:
1.5 区间
区间表达式由具有操作符形式 .. 的 rangeTo 函数辅以 in 和 !in 形成。
区间是为任何可比较类型定义的,但对于整型原生类型,它有一个优化的实现。以下是使用区间的一些示例:
1.6 延迟初始化
具体是这么写的:
🏝️ lateinit var view: View这个
lateinit的意思是:告诉编译器我没法第一时间就初始化,但我肯定会在使用它之前完成初始化的。它的作用就是让 IDE 不要对这个变量检查初始化和报错。换句话说,加了这个
lateinit关键字,这个变量的初始化就全靠你自己了,编译器不帮你检查了。1.7 类和对象
1) 类的继承的写法,Java 里用的是
extends,而在 Kotlin 里使用:,但其实:不仅可以表示继承,还可以表示 Java 中的implement。2)使用
is关键字进行「类型判断」,直接进行强转调用呢?可以使用as关键字1.8 延迟初始化的实现
lateinit 只用于变量 var,而 lazy 只用于常量 val
lazy 应用于单例模式(if-null-then-init-else-return),而且当且仅当变量被第一次调用的时候,委托方法才会执行。
lazy()是接受一个 lambda 并返回一个Lazy <T>实例的函数,返回的实例可以作为实现延迟属性的委托: 第一次调用get()会执行已传递给lazy()的 lambda 表达式并记录结果, 后续调用get()只是返回记录的结果。val lazyValue: String by lazy { println("computed!") "Hello" } fun main(args: Array<String>) { println(lazyValue) println(lazyValue) } 打印结果 computed! Hello Hello1.9 by 关键字的使用
Kotlin 中 by 关键字用来简化实现代理 (委托) 模式,不仅可以类代理,还可以代理类属性, 监听属性变化,下面我们来介绍by的几种主要使用场景:
-
类的代理 class
-
属性延迟加载 lazy
-
可观察属性 Delegates.observable ( 扩展 Delegates.vetoable )
-
自定义监听属性变化 ReadWriteProperty
-
属性非空强校验 Delegates.notNull()
-
Map值 映射到类属性 map
private val model: NameViewModel by viewModels()
2.1 kotlin创建数组
(1)Kotlin语言使用Array表示数组。
(2)[] 可以用于访问数组的元素, [] 被进行了操作符的重载,调用的是 Array 类的 setter 和 getter 方法
2.1.1 创建空数组
val arrayEmpty = emptyArray<String>()
2.1.2 创建指定长度的空数组
val array1 = arrayOfNulls<Int>(5)
for (i in 0..4) {
array1[i] = i
}
2.1.3 创建指定长度的数组
val array4 = Array(5, {0})
初始化长度为5,元素均为0的数组
val array5 : Array<String> = Array(5, {""})
for (i in 0..2) {
array5[i] = i.toString()
}
初始化长度为5,元素均为""的数组,并为数组前3个元素赋值,"0", "1", "2", "", ""
2. 1. 4 使用kotlin封装创建数组
val array1 = arrayOf(1, 2, 3, 4)
val array2 = intArrayOf(1, 2, 3, 4)
2.1.5 遍历数组
val array7 = Array(4, { i -> i * i }) //0,1,4,9,16
// 遍历数组元素 for (item in array7) { println(item) }
// 遍历数组下标 for (item in array7.indices) { println(item) }
// 迭代器遍历数组1 val it = array7.iterator() for (item in it.iterator()) { println(item) }
// 迭代器遍历数组2 val it1 = array7.iterator() it1.forEach { println(it) }
// forEach遍历数组 array7.forEach { println(it) }
2.2 集合处理
主要有三個類別:
- List:可儲存重複值,用索引值 (Index) 取值,為有序排列。
- Set:儲存在
Set的內容都是唯一的,為無序排列。 - Map* :採用 Key-Value 的方式儲存,用 Key 可以取得 Value。
註:Map 雖然不是繼承 Collection,但仍歸納於集合函數內。
上面三個類別都是不可修改內容的,也就是說當 List Set Map 建立出來之後,就無法修改其內容了。但是,個別有一個可以繼承原類型可修改的類型:
- MutableList:可修改的 List。
- MutableSet:可修改的 Set。
- MutableMap:可修改的Map。
2.3 object是Kotlin中的一个重要的关键字,也是Java中没有的。
object是Kotlin中的一个重要的关键字,也是Java中没有的。object主要有以下三种使用场景:
- 对象声明(Object Declaration)
- 伴生对象(Companion Object)
- 对象表达式(Object Expression)
2.3.1 对象声明(Object Declaration)
- 语法含义:将类的声明和定义该类的单例对象结合在一起(即通过object就实现了单例模式) 2) 基本示例
object RepositoryManager{ fun method(){ println("I'm in object declaration") } } 即将class关键字替换为object关键字,来声明一个类,与此同时也声明它的一个对象。只要编写这么多代码,这个类就已经是单例的了。
代码测试验证:fun main(args: Array) { RepositoryManager.method() }
2.3.2 伴生对象(Companion object)
在Kotlin中是没有static关键字的,也就是意味着没有了静态方法和静态成员。那么在kotlin中如果要想表示这种概念,取而代之的是包级别函数(package-level function)和我们这里提到的伴生对象。
class A{ companion object 伴生对象名(可以省略){ //define method and field here } }
2.3.3 对象表达式(Object Expression)
该对象表达式,实现的就是java中匿名内部类的功能。
b. 一个匿名内部类肯定是实现了一个接口或者是继承一个类,并且只能是一个,用数学术语说是“有且只有一个”
- 语法形式:
object [ : 接口1,接口2,类型1, 类型2]{} //中括号中的可省略
- 使用示例:
a. 实现一个接口或类
interface AA { fun a() }
fun main(args: Array<String>) {
val aa = object : AA {
override fun a() {
println("a invoked")
}
}
aa.a()
}
b. 实现多个接口和类
fun main(args: Array<String>) {
val cc = object : AA, BB() {
override fun a() {
}
override fun b() {
}
}
cc.a()
cc.b()
}
2.4 when的使用
- 可以实现switch的功能
- when也可以作为一个表达式
2.5 Any的使用
2.5.1 基本数据类型
在 Kotlin 中,所有东西都是对象,在这个意义上讲我们可以在任何变量上调用成员函数与属性。Byte、Short、Int、Long、Float、Double 、Char