Kotlin的技术演进与核心优势

1.发展历程

2011 年,JetBrains 公司正式推出 Kotlin——一门基于 Java 虚拟机(JVM)的静态类型编程语言,为开发者提供继 Java 和 Scala 后的现代化替代方案。2017 年,Google 在与 Oracle 的 Java 版权诉讼胜诉后,立即将 Kotlin 确立为 Android 官方开发语言。这一战略决策推动 Kotlin 从潜力语言升级为全球最大移动生态系统的首选语言,其采用率在 Android 开发中持续领先(据 2023 年 Google I/O 数据,超 95% 的 TOP 1000 Android 应用使用 Kotlin)。

2.语言特性

Kotlin 融合了函数式与面向对象编程范式,通过精炼语法实现高效表达:

  • 现代化特性:空安全机制、扩展函数、协程、智能类型推断

  • 无缝互操作性:完全兼容 Java 生态,支持混合编译与双向调用

  • 开发效率提升:较 Java 减少 40% 以上的样板代码(JetBrains 官方数据)

3.跨平台能力

作为通用型语言,Kotlin 突破 JVM 限制:

  • 原生编译:通过 Kotlin/Native 编译为 Windows/Linux/macOS 原生二进制

  • 全栈覆盖:支持 Android(移动端)、JavaScript(Web 前端)、Native(桌面端及嵌入式)

  • 共享逻辑:借助 KMM(Kotlin Multiplatform Mobile)实现跨平台业务逻辑复用

4.行业价值

Kotlin 系统性解决了 Java 的历史痛点(如 NPE 风险、冗长语法),同时保留其稳健性。其类型系统增强安全性,协程机制优化并发性能,使得开发可靠性提升 70% 以上(Gartner 2024 报告)。目前已被 Spring Framework、Twitter、Netflix 等企业广泛采用,成为微服务、云原生及跨平台开发的高效解决方案。

Kotlin与JVM

第一种(JVM模式):kotlin源码经其编译器编译后,生成符合JVM规范的字节码运行在JVM上,JVM将字节码转换为机器指令(CPU指令),最终由操作系统(Windows/Linux/macOS)执行。

第二种(非JVM模式):跳过 JVM 和字节码,直接输出目标平台的 CPU 指令(如 iOS 的 ARM 指令)

变量与常量

1.Hello World案例

fun main() {
    // var用于声明变量;str是变量名,后面追加“:”与变量类型隔开;String是变量类型,"Hello World"是变量的值
    var str: String = "Hello World"
    println(str)
}

由上面的 案例可以总结出,我们在KT中初始化一个变量格式如下:

2.只读变量

声明可修改变量,使用var关键字。
声明只读变量,使用val关键字。

//只读变量并非绝对只读
val str2="我是只读变量"
//str2="改变值,哎呦报错了!"

为什么说只读变量并非只读?

var和 val最大的区别就是是否设置了 get和 set,我们都知道 var同时设置 get和 set,但是在 val中只有 get,但当 val变量作为成员变量时,我们修改其 get方法

class Kt01 {
    var currentAge = 10
    val age: Int
        //coerceAtLeast 表示返回值至少是36
        get() = currentAge.coerceAtLeast(36)
}

fun main() {
    val kt01 = Kt01()
    println("age = ${kt01.age}")
    kt01.currentAge = 66
    println("30年后,age = ${kt01.age}")
}

 

发现被 val修饰的 age变成66了 。

3.类型推断

对于已初始化的变量,kt允许我们省略类型定义。

4.编译时常量

在 Kotlin 中,编译时常量const val)必须满足以下核心约束:

  1. 声明位置限制
    编译时常量只能在顶级作用域(文件层级)或对象声明object/companion object)中定义,不可在函数内部声明。原因在于:

    • 编译时常量的值必须在编译期由常量表达式确定,其值会被直接内联到使用位置,不参与运行时初始化过程。

    • 函数内的变量属于运行时数据(函数调用时才初始化)

  2. 数据类型限制
    编译时常量仅支持基本字面量类型
    StringIntDoubleFloatLongShortByteCharBoolean
    注:复杂类型(如自定义类/集合)因需运行时构造,不被允许

const val MY_NAME: String = "luffy"
const val MAX: Int = 666
const val DOUBLE: Double = 66.88
const val FLOAT: Float = 66.99F
const val LONG: Long = 2021L
const val SHORT: Short = 2
const val BYTE: Byte = 6
const val CHAR: Char = 'A'
const val BOOLEAN: Boolean = true
fun main() {
    println(MY_NAME)
    println(MAX)
    println(DOUBLE)
    println(FLOAT)
    println(LONG)
    println(SHORT)
    println(BYTE)
    println(CHAR)
    println(BOOLEAN)
}

Kotlin的数据类型 

常用数据类型

kotlin只提供引用数据类型这一种数据类型,出于更高性能的考虑,kotlin编译器会在Java字节码中改用基本数据类型。

注:双击shift,输入show kotlin bytecode即可查看kotlin字节码。或者Tools->Kotlin->Show Kotlin Bytecode。

表达式

if / if else / if else if 表达式跟Java一样,不再赘述。

rang表达式:in A..B,in关键字用来检查某个值是否在指定范围之内,比如 in 1..100 表示[1,100]闭区间,in 后面也可以跟 List、Map等。

const val MONEY: Int = 399
fun main() {
    // Rangs表达式,原型:override fun contains(value: Int): Boolean = first <= value && value <= last
    if (MONEY in 1..100) {
        println("您可预约单身公寓")
    } else if (MONEY in 101..200) {
        println("您可预约大床房")
    } else if (MONEY in 201..360) {
        println("您可预约情侣商旅酒店")
    } else {
        println("贵宾您办卡的话本次消费免费哟~")
    }
}
    val age = 3
    val ageList = listOf(1, 2, 3, 4, 5, 6, 7, 8)
    if(age in ageList){
        println("${age}岁大的人是婴幼儿。")
    }

 when表达式

与C和Java中的switch...case语句类似,表示满足某个条件,执行指定代码,只要代码包含else if,都可以用when表达式替代。

const val school = "大学"
fun main() {
    main1()
    val level = when (school) {
        "幼儿园" -> "幼儿"
        "小学" -> "儿童"
        "中学" -> "少年"
        "大学" -> "大龄儿童"
        "工作三五年" -> "油腻大叔"
        else -> "你怕是神仙吧~"
    }
    print(level)
}

String模板
①模板支持在字符串的双引号中放入变量,变量前加 $符;
②支持字符串中插入表达式的值,表达式需要插入到${}中。

fun main() {
    val food = "carrot"
    println("My favorite is $food")
    println("1比2大?${if (1 > 2) "对的" else "不对"}")
}

函数

定义一个函数

格式:

入参放在前面更科学,先有输入后有输出。
案例: 

fun main() {
    val sum = getSum(1, 5)
    println(sum)
}

/**
 * private是修饰符,不指定修饰符,默认是public
 * fun是声明函数的关键字
 * getSum是函数名
 *
 * @param a 函数的第一个参数
 * @param b 函数的第二个参数
 * @return 类型是Int, 是a和b的和
 */
private fun getSum(a: Int, b: Int): Int {
    return a + b
}

默认值参(Java没有这种语法)

如果不打算传入值参,可以预先给参数指定默认值。

/**
 * 如果不打算传入值参,可以预先给参数指定默认值。
 * 比如该函数第二个参数默认传入“Honey”
 */
private fun doSomething(firstOne: String, secondOne: String = "Honey") {
    println("$firstOne love $secondOne forever")
}

具名函数参数(Java没有这种语法)

如果使用命名值参,可以不用关心值参顺序。

    //具名值参
    doSomething(secondOne = "Honey",firstOne = "Luffy")

无返回值类型

Unit类型

不是所有的函数都有返回值,kt中没有返回值的函数叫Unit函数,Unit跟Java中的void类型比较像,都表示无返回值类型,但是 void无法解释泛型这一现代语言特性。

    //kotlin.Unit 无返回值类型
    println(doSomething("Luffy"))

 Noting类型

    //Nothing类型:内置函数TODO返回值就是Noting
    TODO("你不要走好不好,跑起来,哇哈哈哈,快,跑起来!")
    println("after TODO")

我们可以参照TODO的方式返回Nothing类型,终止我们的程序。

反引号中的函数名

Kotlin可以使用空格和特殊字符对函数命名,不过函数名需要用一堆反引号括起来。这种写法是为了支持Kotlin和Java互操作,因为Kotlin和Java各自有不同的关键字,不能作为函数名,使用反引号可以避免冲突。

Java 和 Kotlin互调用案例:

//以下是在 MyKotlin.kt 定义的代码:
fun main() {
    MyJava.`is`()
    `**special function of test special function**`()

/**
 * 测试特殊功能的函数
 */
fun `**special function of test special function**`() {
    println("测试特殊功能的函数!")
}

fun isKotlin(){
    println("isKotlin invoked!")
}


//以下是Java代码:
public class MyJava {
    public static void main(String[] args) {
        MyKotlinKt.isKotlin();// 文件名映射:Kotlin 顶级函数会生成在 [文件名]Kt 类中(如 KotlinMain.kt → KotlinMainKt)
    }

    public static void is() {
        System.out.println("JavaMain: is invoked!");
    }
}

这一讲先讲这么多,欲知后事如何,且听下回分说~欢迎大家评论加点赞,大伙的支持对我很重要哦(≧◉◡◉≦)

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐