基础语法

本章对应 Kotlin 官方文档中的基础语法概览,并加入 Java 对比说明。建议你把 Kotlin 当作一门新语言学习,而不是“Java 的简写版”。

包与导入

Kotlin 文件可以声明包:

package com.example.demo

import kotlin.math.max

fun main() {
    println(max(10, 20))
}

与 Java 不同,Kotlin 的包名不强制要求与目录结构完全一致。实际项目中仍建议保持一致,因为这样更符合 IDE、构建工具和团队习惯。

程序入口

Kotlin 应用的入口是 main 函数:

fun main() {
    println("Hello, Kotlin")
}

如果需要命令行参数:

fun main(args: Array<String>) {
    println(args.contentToString())
}

Java 写法通常需要类和静态方法:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, Java");
    }
}

Kotlin 允许顶层函数,所以简单程序不需要额外包一层类。

输出与输入

fun main() {
    print("请输入名字:")
    val name = readln()
    println("你好,$name")
}
  • print() 不换行。
  • println() 输出后换行。
  • readln() 读取一整行字符串。

变量:valvar

Kotlin 声明变量时,把关键字放在前面:

val language = "Kotlin"
var count = 1

count += 1
  • val:只读引用,只能赋值一次。
  • var:可重新赋值。

注意:val 不等于“深度不可变”。

val names = mutableListOf("Ada")
names.add("Grace")      // 可以,列表对象本身是可变的
// names = mutableListOf("Linus") // 不可以,names 这个引用不能重新指向别的列表

Java 对比:

final List<String> names = new ArrayList<>();
names.add("Ada");       // 可以
// names = new ArrayList<>(); // 不可以

val 更接近 Java 的 final 局部变量,而不是不可变集合。

类型推断

Kotlin 通常可以推断变量类型:

val age = 18          // Int
val name = "Kotlin"   // String

需要强调公共 API、避免歧义或延迟初始化时,可以显式写类型:

val port: Int = 8080
val users: List<String> = emptyList()

函数

完整写法:

fun sum(a: Int, b: Int): Int {
    return a + b
}

表达式函数体:

fun sum(a: Int, b: Int) = a + b

没有有意义返回值时,返回类型是 Unit,通常省略:

fun printSum(a: Int, b: Int) {
    println(a + b)
}

Java 的 void 表示“没有返回值”;Kotlin 的 Unit 是一个真实类型,只是多数情况下不需要显式写出来。

类与实例

最简单的类:

class User

带属性和主构造函数:

class User(val id: Long, var name: String)

fun main() {
    val user = User(1, "Alice")
    println(user.name)
    user.name = "Bob"
}

这段 Kotlin 大致对应 Java 中的构造器、字段、getter 和 setter。区别是 Kotlin 把“构造参数”和“属性声明”合并在类头部,减少样板代码。

注释

// 单行注释

/*
 多行注释
*/

Kotlin 的块注释可以嵌套:

/*
 外层注释
 /*
  内层注释
 */
*/

字符串模板

val name = "Kotlin"
println("Hello, $name")
println("Name length: ${name.length}")

简单变量可以用 $name,复杂表达式用 ${...}。这比 Java 的字符串拼接更自然,也比 String.format() 更轻量。

条件表达式

Kotlin 没有 Java 风格三元运算符,因为 if 本身可以返回值:

fun maxOf(a: Int, b: Int): Int {
    return if (a > b) a else b
}

表达式写法:

fun maxOf(a: Int, b: Int) = if (a > b) a else b

循环

遍历集合:

val items = listOf("apple", "banana", "kiwi")

for (item in items) {
    println(item)
}

遍历索引:

for (index in items.indices) {
    println("$index -> ${items[index]}")
}

更推荐需要索引和值时使用:

for ((index, item) in items.withIndex()) {
    println("$index -> $item")
}

when

when 类似 Java 的 switch,但更强大:

fun describe(value: Any): String =
    when (value) {
        1 -> "数字 1"
        "hello" -> "问候语"
        is Long -> "Long 类型"
        !is String -> "不是字符串"
        else -> "未知"
    }

when 可以匹配值、类型、范围和任意布尔条件。作为表达式使用时必须覆盖所有情况,通常通过 else 或枚举、密封类的穷尽分支完成。

范围

for (i in 1..5) {
    print(i) // 12345
}

for (i in 5 downTo 1) {
    print(i) // 54321
}

for (i in 1..10 step 2) {
    print(i) // 13579
}

判断是否在范围内:

val x = 10
if (x in 1..100) {
    println("有效")
}

空值初见

普通类型不能保存 null

val name: String = "Kotlin"
// val bad: String = null // 编译错误

可空类型需要显式加 ?

val name: String? = null
println(name?.length)

这是 Kotlin 与 Java 最重要的差异之一。Java 中任何引用理论上都可能是 null;Kotlin 把这个事实写进类型系统。

参考

  • 官方基础语法:https://kotlinlang.org/docs/basic-syntax.html