Kotlin

语言学习

Posted by LXG on July 2, 2025

kotlin 对比 java

维度 Kotlin Java
语法简洁性 ✅ 更简洁(支持类型推导、默认参数等) ❌ 相对繁琐(代码冗长)
空指针安全 ✅ 内建 Null 安全系统 ❌ Null 是常见错误来源
扩展函数支持 ✅ 支持 ❌ 不支持
协程支持 ✅ 内置协程(轻量线程) ❌ 需要使用线程或第三方库
Lambda 表达式 ✅ 原生支持 ✅ Java 8+ 开始支持
数据类 ✅ 内建 data class ❌ 手写 getter、setter 等
默认不可变性 ✅ 推荐使用 val ❌ 默认可变
类型推导 ✅ 支持类型自动推导 ❌ 必须声明类型
枚举增强 ✅ 支持密封类、when ❌ 功能有限
Android 支持 ✅ 官方推荐语言 ✅ 老牌稳定语言
JVM 兼容性 ✅ 与 Java 完全互通 ✅ 与 Kotlin 可互通(公开 API)
编译速度 ⏳ 稍慢 ⚡ 更快
学习曲线 ⬆️ 稍陡峭 ✅ 容易上手
社区生态 ✅ 活跃增长中 ✅ 非常成熟

build.gradle 和 build.gradle.kts

特性 Groovy (build.gradle) Kotlin (build.gradle.kts)
类型安全 ❌ 弱类型 ✅ 强类型
自动补全与提示 ❌ 弱 ✅ 好(尤其在 Android Studio Arctic Fox+)
脚本灵活性 ✅ 高(支持较多 DSL 魔法) ⚠️ 限制较多,语法更严格
编写易用性 ✅ 语法宽松 ⚠️ 容易踩坑,尤其是早期版本 Gradle 插件
编译性能 ⚠️ 稍慢 ✅ 稍快(Gradle 7.0+ 表现更佳)
官方趋势 ✅ 兼容主流项目 ✅ Google 已推荐新项目使用 Kotlin DSL

settings.gradle.kts


pluginManagement {
    repositories {
        google()
        maven {
            url = uri("https://maven.aliyun.com/repository/gradle-plugin")
            content {
                includeGroupByRegex("com\\.android.*")
                includeGroupByRegex("com\\.google.*")
                includeGroupByRegex("androidx.*")
            }
        }
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        maven { url = uri("https://maven.aliyun.com/repository/public") }
        maven { url = uri("https://maven.aliyun.com/repository/google") }
        maven { url = uri("https://maven.aliyun.com/repository/jcenter") } // 已经废弃,仅用于老项目
        google()
        mavenCentral()
    }
}

rootProject.name = "AccessibilityDemo"
include(":app")

build.gradle.kts


// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.kotlin.android) apply false
    alias(libs.plugins.kotlin.compose) apply false
}

app/build.gradle.kts


plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
    alias(libs.plugins.kotlin.compose)
}

android {
    namespace = "com.wif.demo"
    compileSdk = 35

    defaultConfig {
        applicationId = "com.wif.demo"
        minSdk = 24
        targetSdk = 35
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = "11"
    }
    buildFeatures {
        compose = true
    }
}

dependencies {

    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
}

gradle/libs.versions.toml


[versions]
agp = "8.10.1"
kotlin = "2.0.21"
coreKtx = "1.10.1"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
lifecycleRuntimeKtx = "2.6.1"
activityCompose = "1.8.0"
composeBom = "2024.09.00"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

关系图


libs.versions.toml
  │
  └──▶ 提供版本号和别名(比如 agp、kotlin、compose)
           │
           ▼
settings.gradle.kts
  ├── 设置插件仓库 pluginManagement { ... }
  ├── 设置依赖仓库 dependencyResolutionManagement { ... }
  └── include(":app") 指定模块
           │
           ▼
build.gradle.kts(每个模块)
  ├── 使用 plugins { alias(...) } 引入插件
  └── 使用 dependencies { implementation(...) } 引入依赖


基本语法

  1. 变量 val var
  2. 运算符 与java一致
  3. 字符串
  4. 字符串操作函数
  5. 模板表达式
  6. 条件语句
  7. when 字符,kotlin没有switch关键字
  8. 循环语句 while for
  9. 跳转语句 continue break
  10. 区间
  11. 数组
  12. 变量的类型转换
  13. 可空变量 非空变量
  14. ?: 操作符

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val int_a: Int = 1
        val Str_a: String = "hello"

        Log.d("LXG", Str_a)
        Log.d("LXG", "" + Str_a[3])

        val number: IntArray = intArrayOf(1, 2, 3, 4)
        var bool_array: BooleanArray = booleanArrayOf(true, true, false)
        var char_array: CharArray = charArrayOf('a', 'b')

        val int_array: Array<Int> = arrayOf(1, 2, 3)

        var string_array: Array<String> = arrayOf("hello", "world")

        
        var num1 = 1
        val s1 = "a is ${num1}"
        val s2 = "a is $num1"
        Log.d("LXG", "" + s1)
        Log.d("LXG", "" + s2)

        var month: Int = 7
        when(month) {
            12,1,2 -> println("冬季")
            3,4,5 -> println("春季")
            6,7,8 -> println("夏季")
            9,10,11 -> println("秋季")
            else -> println("未知")
        }

        var a: Int = 7
        var b: Int = 8
        when {
            a > b -> println("a 大于 b")
            a < b -> println("a 大于 b")
            else -> println("a 等于 b")
        }

        for (i in 0..3) {
            println("i = $i")
        }
        
        number.forEach { println(it.toString() + "\t") }

        string_array.forEachIndexed() {index, s -> println("index = $index , s = $s") }

        // 区间
        for (i in 1.rangeTo(4)) {
            println("i = $i")
        }

        for (i in 4.downTo(1)) {
            println("i = $i")
        }

        for (i in 4.downTo(1) step 2) {
            println("i = $i")
        }

        // 数组
        for ((index, i) in bool_array.withIndex()) {
            println("index = $index , s = $i")
        }
        println("4, index = " + number.indexOf(4))

        var name: String = "Tom" // 非空变量
        var telephone : String? = null
        var result = telephone?.length
        println(result)

    }