官方
官方版本
github
基础
数据类型
- 整数
类型 | 大小(比特数) | 最小值 | 最大值 |
---|---|---|---|
Byte | 8 | -128 | 127 |
Short | 16 | -32768 | 32767 |
Int | 32 | -2,147,483,648 (-231) | 2,147,483,647 (231 - 1) |
Long | 64 | -9,223,372,036,854,775,808 (-263) | 9,223,372,036,854,775,807 (263 - 1) |
- 浮点数
类型 | 大小(比特数) | 有效数字比特数 指数比特数 | 十进制位数 | |
---|---|---|---|---|
Float | 32 | 24 | 8 | 6-7 |
Double | 64 | 53 | 11 | 15-16 |
可见性修饰符
类、对象、接口、构造函数、方法、属性和它们的 setter 都可以有 可见性修饰符
- public(默认是public,随处可见)、private(文件内可见)、protected(private一样 + 在子类中可见)
- 新增internal 表示当前模块可⻅
控制流
- for循环
repeat(100) {
// todo
}
for (index in 1..100){
print(index)
}
for (index in 1 until 10){
println(index)//输出0..9
}
for (index in 1..100 step 2){
print(index)//会输出1..3..5......
}
for (index in 100 downTo 1){
print(index)
}
- when (可以取代if-else-if)
when (direction) {
0 -> setCompoundDrawables(drawable, null, null, null)
1 -> setCompoundDrawables(null, drawable, null, null)
2 -> setCompoundDrawables(null, null, drawable, null)
3 -> setCompoundDrawables(null, null, null, drawable)
else -> throw NoSuchMethodError()
}
- Elvis (可以通过 ?: 的操作来简化 if null 的操作)
val date = lesson.date?: "⽇期待定"
字符串模板
- 用 ${} 表示字符串模板
val name = "haha"
val text = "${name}"
val text = "$name"// 如果只是单⼀的变量,可以省略掉 {}
- 通过⼀对 """ 的⽅式来代替 \n 拼接的多⾏字符串。
变量
- 只读变量 val
- 可读写变量 var
- 静态常量前面加上const,表示编译器常量 ,类似java的public static final string
空安全设计
- 不可空类型 EditText
- 可空类型 EditText?
- 强行调用 !!
- 安全调用 ?.
- lateinit
lateinit 使用注意如下:
- 只能修饰var变量
- 修饰的变量必须是不可空的变量
- 不能有初始值
- 不能是基本数据类型
平台类型
在类型后面加上!,为平台类型,java通过注解释来减少平台类型的产生
- @Nullable 表示可空类型
- @NotNull @NonNull 表示不可空类型
类型判断
- is属于某类型
- !is 不属于某类型
- as 类型强转,失败时候抛出异常
- as? 类型强转,失败时抛出null
获取class对象
- 类名::class, 是Kotlin获取的KClass类型的
- 类名::class.java 是Java获取的class类型的
声明接⼝/抽象类/枚举/注解
// 声明抽象类
abstract class
// 声明接⼝
interface
// 声明注解
annotation class
// 声明枚举
enmu class
数组与集合
- List 以固定顺序存储一组元素,元素可以重复。
val strs: List = listOf("a", "b", "c")
val anys: List = strs // success
- Kotlin 中的 List 多了一个特性:支持 covariant(协变)。也就是说,可以把子类的 List 赋值给父类的 List 变量。java中为了类型安全,存在泛型中在编译期间会类型擦除,所以不支持协变。
- 什么时候用数组,什么时候用集合?如果是基本类型的时候,建议用数组,这样可以不用自动装箱拆箱操作,否则建议用集合以为集合api比较丰富,
- Set 存储一组互不相等的元素,通常没有固定顺序。
val strSet = setOf("a", "b", "c")
- Map 存储 键-值 对的数据集合,键互不相等,但不同的键可以对应相同的值。
val map = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 3)
val map = mutableMapOf("key1" to 1, "key2" to 2)
map.put("key1", 2)
map["key1"] = 2
4.listOf() 创建不可变的 List,mutableListOf() 创建可变的 List。
setOf() 创建不可变的 Set,mutableSetOf() 创建可变的 Set。
mapOf() 创建不可变的 Map,mutableMapOf() 创建可变的 Map。
- 使用toMutableList可以是不可变集合变成可变集合
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()
类和对象
data class(数据类,实体类)
Kotlin 使用data修饰实体类,数据类会同时构造出以下方法
- toString()
- hashCode()
- equals()
- copy() (浅拷⻉)
对基本数据类型进行copy,对数据类型只是引用,没有真实创建一个新的对象,叫浅copy
对引用数据类型时候,创建一个新的对象,并复制其内的成员变量,则为深copy
- componentN()
可以把一个对象解构多个属性
val (code, message, body) = response
val code = response.component1()
val message = response.component2()
val body = response.component3()
objec
- 修饰类,被修饰的类可以作为单例对象,里面的变量以及函数,可以当做雷士java中静态变量,静态方法使用,使用类点的形式使用;
//class 替换成了 object
object A {
val number: Int = 1
fun method() {
println("A.method()")
}
}
- 可以当做匿名内部类
//java调用匿名内部类
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
//kotlin使用object调用匿名内部类
userName.setOnClickListener(object :View.OnClickListener{
override fun onClick(p0: View?) {
TODO("Not yet implemented")
}
})
Companion objec 伴生对象
在类内部维护一个单例对象
class A {
companion object B {
var c: Int = 0
}
}
函数
构造函数
Kotlin构造函数,直接用constructor,取代java中和类同名
- 主构造不能包含任何代码,初始化代码可以放到init{}方法里面;
class CodeView constructor(context: Context) : TextView(context) {
init {
//setTextSize()
}
val paint = Paint() // 会在 init{} 之后运⾏
}
- 主构造函数和次级构造函数
- 把最基本的函数作为主构造函数,因为主构造函数会参与所有的次级构造函数初始化过程
- 构造函数里面参数加上var,会在类里面自动生成get和set方法
函数
- 函数简化: 一般函数体只有一行代码,可以省略大括号,作为函数体加等号放到函数的右边
fun test()=println("test")
- 函数参数默认值,可以少写部分重载方法
fun CharSequence.showToast(duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(EyepetizerApplication.context, this, duration).show()
}
- @JvmOverloads
使⽤ @JvmOverloads 对 Java 暴露重载函数
top-level functions (顶层函数)
函数放到类的外面,一般工具类的开发使用顶层函数,方便调用,开发重复;
inline(内联函数)
使⽤ inline 关键字声明的函数是「内联函数」,在编译时会将「内联函数」中的函数体,直接插⼊到
调⽤出。内涵函数意义:
- 减少一层调用栈
- 推荐函数类型时使用
infix函数
自定义中缀函数,用来做扩展函数
- 只有一个参数
- 在方法前必须加infix关键字
- 必须是成员方法或者扩展方法
infix fun Int.add(x: Int): Int {
return this + x
}
println(100 add 200)
高阶函数
Kotlin高阶函数的使用
扩展
- 扩展函数可以为任何类添加上⼀个函数,从⽽代替⼯具类
- 扩展函数和成员函数相同时,成员函数优先被调⽤
- 扩展函数是静态解析的,在编译时就确定了调⽤函数(没有多态)
Kotlin 标准函数
- ?.let{}标准函数:
- 用来进行辅助空判断.
- 指定return返回, 或返回最后一行
- with(){}-适合对同⼀个对象进⾏多次操作的时候
with函数接收两个对象, 第一个对象是任意类型的对象, 第二个参数是lambda表达式.
Lambda表达式中会提供第一个参数对象的上下文.
使用Lambda的最后一行代作为返回值返回
- run {}
- 跟with类似. 改为某对象调用run{}函数.
- Lambda最后一行作为返回值
- apply{}-适合对⼀个对象做附加操作的时候
- 跟run函数也类似.
- 但是并无返回值,而是自动返回对象本身.