以下是一份 超详细的 Java 与 Kotlin 对比学习指南,涵盖语法、设计理念和实际场景的深度对比,帮助您从 Java 平滑过渡到 Kotlin。
public class Main {
public static void main(String[] args) {
System.out.println("Hello, Java!");
}
}
public static void main
方法。fun main() {
println("Hello, Kotlin!")
}
// 或带参数
fun main(args: Array<String>) {
println(args.joinToString())
}
main
函数。println
是 Kotlin 标准库函数,无需 System.out
。final String name = "Java"; // 不可变
int age = 25; // 可变
Integer nullableAge = null; // 可空包装类型
final
声明常量。int
)不能为 null
,需用包装类型(Integer
)。val name = "Kotlin" // 不可变(类型推断为 String)
var age = 25 // 可变
var nullableAge: Int? = null // 可空类型(显式声明)
val
类似 final
,var
可变。?
表示可空,编译时强制检查。public int sum(int a, int b) {
return a + b;
}
// 重载
public int sum(int a, int b, int c) {
return a + b + c;
}
public
)。fun sum(a: Int, b: Int) = a + b // 单行表达式
fun sum(a: Int, b: Int, c: Int = 0) = a + b + c // 默认参数
{}
和 return
)。public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getter/setter 省略...
}
class Person(val name: String, var age: Int) // 主构造函数
val
生成只读属性(只有 getter),var
生成可变属性(getter/setter)。public class Animal {
public void eat() { ... }
}
public class Dog extends Animal {
@Override
public void eat() { ... }
}
extends
和 implements
关键字。final
修饰)。open class Animal { // 必须用 open 允许继承
open fun eat() { ... } // 允许重写的方法需 open
}
class Dog : Animal() {
override fun eat() { ... }
}
final
,需显式标记 open
才能继承/重写。:
替代 extends
/implements
。public class User {
private int id;
private String name;
// 需手动实现 equals(), hashCode(), toString()
// 或使用 Lombok @Data
}
data class User(val id: Int, val name: String)
equals()
、hashCode()
、toString()
、copy()
等。String str = null; // 允许
int length = str.length(); // 运行时 NullPointerException
@Nullable
)或手动判空。var str: String? = null // 必须显式声明可空
val length = str?.length // 安全调用(返回 Int?)
val nonNullLength = str!!.length // 非空断言(可能抛 NPE)
val safeLength = str?.length ?: 0 // Elvis 操作符
NullPointerException
。List<String> list = Arrays.asList("a", "b", "c");
list.add("d"); // 抛出 UnsupportedOperationException(不可变)
List<String> mutableList = new ArrayList<>(list);
val list = listOf("a", "b", "c") // 不可变
val mutableList = mutableListOf("a", "b") // 可变
List<Integer> numbers = Arrays.asList(1, 2, 3);
List<Integer> evens = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
val numbers = listOf(1, 2, 3)
val evens = numbers.filter { it % 2 == 0 } // 更简洁
Runnable task = () -> System.out.println("Running");
Collections.sort(list, (a, b) -> a.compareTo(b));
val task = { println("Running") }
list.sortedBy { it } // 更自然的语法
public interface Operation {
int execute(int a, int b);
}
public int calculate(int a, int b, Operation op) {
return op.execute(a, b);
}
// 调用
calculate(2, 3, (a, b) -> a + b);
fun calculate(a: Int, b: Int, op: (Int, Int) -> Int) = op(a, b)
// 调用
calculate(2, 3) { x, y -> x + y }
new Thread(() -> {
try {
Thread.sleep(1000);
System.out.println("Done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
GlobalScope.launch {
delay(1000L) // 挂起函数,不阻塞线程
println("Done")
}
无法直接扩展类,需通过工具类:
public class StringUtils {
public static String reverse(String s) {
return new StringBuilder(s).reverse().toString();
}
}
String reversed = StringUtils.reverse("hello");
fun String.reverse() = this.reversed()
val reversed = "hello".reverse()
Kotlin 可直接使用 Java 类和库:
val javaList = ArrayList<String>() // Java 的 ArrayList
javaList.add("Kotlin")
顶级函数
在 Java 中通过生成的类调用:// Kotlin 文件:Utils.kt
fun log(message: String) { ... }
// Java 调用
UtilsKt.log("Hello");
// Kotlin
class MyClass {
companion object {
fun create() = MyClass()
}
}
// Java 调用
MyClass.Companion.create();
特性 | Java | Kotlin |
---|---|---|
变量声明 | final + 类型显式 |
val /var + 类型推断 |
空安全 | 需手动检查或注解 | 编译时强制检查(? 和 !! ) |
函数式编程 | Stream API(Java 8+) | 原生支持(Lambda、扩展函数) |
数据类 | 手动编写或 Lombok | data class 自动生成 |
并发 | 线程/ExecutorService | 协程(轻量级线程) |
扩展机制 | 静态工具类 | 扩展函数/属性 |
与 Java 互操作 | 天然兼容 | 100% 兼容,但需注意空安全注解 |
data class
替代 Java Bean。@Nullable
/@NotNull
注解。通过对比学习,可以更深入理解 Kotlin 的设计哲学,写出更简洁、安全的代码!