Kotlin——基础语法
定义函数
带有两个Int参数、返回Int的函数:
| 1 | fun sum(a: Int, b: Int): Int { | 
表达式作为函数体、返回值类型自动推断的函数:
| 1 | fun sum(a: Int, b: Int) = a + b | 
返回无意义的值:
| 1 | fun printSum(a: Int, b: Int): Unit { | 
省略Unit返回类型:
| 1 | fun printSum(a: Int, b: Int) { | 
定义变量
只读变量
只读变量用val修饰:
| 1 | val a: Int = 1 //立即赋值 | 
可变变量
可变变量用var修饰:
| 1 | var x = 5 //自动推断出Int类型 | 
Android Studio Java 和 Kotlin混合编译配置
Java和Kotlin的混编,按场景分一下两种:
- Java 调用 Kotlin(如Java编写的Activity里面按钮点击,开启一个Kotlin编写的Activity
- Kotlin 调用 Java(如Kotlin编写的Activity里面按钮点击,开启一个java编写的Activity
具体配置
下面讲一下怎么配置才能满足混合编译的配置
- 根项目下的build.gradle文件配置: - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24- buildscript { 
 ext.kotlin_version = '1.6.10'
 repositories {
 ...
 }
 dependencies {
 // gradle 插件版本
 classpath 'com.android.tools.build:gradle:3.6.1'
 // kotlin gradle 插件版本,这个版本要与Android Studio的插件版本序号一致
 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
 // 扩展插件可以节省findviewbyid(),实现与Data-Binding,Dagger框架的效果,不需要添加任何额外代码,也不影响任何运行时体验。
 classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
 // NOTE: Do not place your application dependencies here; they belong
 // in the individual module build.gradle files
 }
 }
 allprojects {
 repositories {
 ...
 }
 }
- module项目下的build.gradle文件配置 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24- apply plugin: 'com.android.application' 
 // 下面两种写法都可以
 //apply plugin: 'org.jetbrains.kotlin.android'
 apply plugin: 'kotlin-android'
 android({
 compileSdkVersion rootProject.ext.android.compileSdkVersion
 buildToolsVersion rootProject.ext.android.buildToolsVersion
 compileOptions {
 sourceCompatibility javaVersion
 targetCompatibility javaVersion
 }
 kotlinOptions {
 jvmTarget = '1.8'
 }
 dependencies {
 dependencies {
 // 这个可以不用,作用Android KTX 是包含在 Android Jetpack 及其他 Android 库中的一组 Kotlin 扩展程序。KTX 扩展程序可以为 Jetpack、Android 平台及其他 API 提供简洁的惯用 Kotlin 代码。
 implementation "androidx.core:core-ktx:1.6.0"
 implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
 }
 }
关于android KTX,请参考Android KTX
这样就可以配置就完成了
问题
Java调用Kotlin没什么问题,主要是在Kotlin的Activity中调用Java方法(或开启Java的Activity)时,如果Java 类文件不在main/java下,就会出现找不到引用的问题,这个目前没有搜到相应的解决办法,后面知道了会跟新记录
NULL检查机制
注意点1
都知道Kotlin有空安全机制,这样可以避免Java中crash最常见的罪魁祸首NPE出现,但还是要知道Kotlin空安全的具体使用的。具体来说,Kotlin对于声明为可为空的参数,在使用时要进行判空处理具体有以下两种方式:
- 可为空字段后面加上!!,表示当字段为空时,会像Java一样抛出空指针异常;
- 可为空字段后面加上?,表示不做处理返回值为null或者配合?:做判空处理;
具体看下面的例子:
| 1 | //类型后面加?表示可为空 | 
注意点2
当引用一个可能为null的值时,对应的类型声明必须明确的标记为可为null
具体例子:
| 1 | // 当 str 中的字符串内容不是一个整数时, 返回 null,函数返回值类型必须为 Int? | 
类型检测及自动类型转换
Kotlin中类型检测采用 is关键字来表示,类似于 Java中的 instanceOf关键字,但Kotlin中会有一个更便捷的地方,就是采用 is检测后,就自动转换成对应的类型了,不用像Java中那样在现实的强转一下,具体看一下例子:
| 1 | fun getStringLength(obj : Any) : Int? { | 
扩展
Kotlin可以对一个类的属性和方法进行扩展,且不许要使用继承或者Decorator模式;
扩展函数可以在已有类
object关键字
kotlin增加了一个 object关键字,该关键字用于以下场景中:
- 对象表达式,相当于Java中的匿名内部类;
- 对象声明,kotlin中提供的一个简洁的单例声明方式;
- 伴生对象,kotlin中替代Java 中static功能的方式;
对象表达式
对象表达式,类似于Java中的匿名内部类:
| 1 | interface OnClickListener { | 
注意:
listener =可以省略
关于对象表达式,还有以下要知道的:
- 对象表达式 object 冒号后面可以有多个超类,
- 对象表达式 的超类如果包含带参数的构造函数,则在声明的时候需要传递相应的参数;
- 匿名对象智能在 本地 和 私有声明 中作为类型使用,如果对象表达式采用了 public 关键字修饰,则匿名对象的实际类型是 匿名对象的超类型(没有超类型则 类型为Any),public 修饰的匿名对象 里成员将不可访问。
- 对象表达式可以访问外部类的成员,并且外部类没必要声明为final,这一点同Java不一样。
对象声明
对象声明是Kotlin (在Scala之后)实现单例的一种快捷方式,即kotlin中可以像声明变量那样采用关键字来声明单例,而不用像Java那样需要自己 去实现单例。这个关键字就是 object,该关键字后面直接接类名时,那么这个类就只有一个对象,例如:
| 1 | object DialogManager : BaseDialogManager() { | 
由上面的示例可见,对象声明 时 类可以有超类。对象声明虽然方便,但也有几个局限的地方:
- 对象声明 时 没有 右值的,所以不能作为表达式那样复制个其他变量,这一点Java的单例是可以的;
- 对象声明 不能 是本地的,即不能放在函数作用域中,可以在类作用域(类里面声明)使用;
- 对象声明 可以继承超类,即单例可以有超类。
伴生对象
伴生对象(companion object)的出现是为了解决 Java 静态方法(static)的反面向对象(Anti-OOP)的问题。即Java 中 static 方法是无法声明为接口、无法被重写的,也就是说 static方法没有面向对象的 消息传递 和 延迟绑定 特性。而Kotlin中一切皆对象,多以采用伴生对象来替代static方法。
companion object 是一个对象,在类初始化时被实例化。注意 伴生对象不是类的 static 方法,而是类的实例化对象,其内部可以声明接口,方法也可以被重写,具备面向对象的特点。
伴生对象声明方式
| 1 | companion object ObjectName : [0~N个父类型] { | 
伴生对象的特点:
- 伴生对象相当于类的对象,可以直接通过类名访问伴生对象的成员;
- 每个类最多定义一个伴生对象;
- kotlin中没有 static关键字,伴生对象是为了弥补kotlin中没有 static 修饰的静态成员的不足;
- @JvmStatic 注解只能用在伴生对象内,修饰伴生对象内的属性和函数;
协程
操作符
- 安全调用操作符 - ?.- 功能:安全调用操作符 ?. 用于在调用方法或访问属性时,确保如果左侧表达式为 null,则整个表达式的值为 null,而不会抛出异常。 
- 使用场景:当你不确定某个对象是否为 null,并且希望在对象为 null 时不执行后续操作时,可以使用 ?.。 
 
- 非空断言操作符 - !!.- 功能:非空断言操作符 !!. 用于强制将一个可空类型的值转换为非空类型。如果该值为 null,则会抛出 NullPointerException。 
- 使用场景:当你确定某个对象不会为 null,并且希望在对象为 null 时立即抛出异常而不是继续执行代码时,可以使用 !!.。