Kotlin 与 Java 核心区别(超详细+代码对比)
Kotlin 是基于 JVM、完全兼容 Java的现代化编程语言,由 JetBrains 开发,2017 年成为 Google 官方推荐的 Android 开发语言,可以直接调用 Java 代码,Java 也能调用 Kotlin 代码,但语法、设计理念、开发效率有巨大差异。
我会从10 个核心维度详细对比,每个点都配Java 代码 ↔ Kotlin 代码示例,新手也能看懂。
一、空安全(最大区别!Kotlin 从根源避免空指针)
Java 最大的痛点:空指针异常(NullPointerException),几乎所有开发者都踩过坑。
Kotlin 默认区分可空类型和非空类型,从编译期就禁止空指针。
Java 代码(会报空指针)
// Java:默认所有变量都可以为 null,编译器不检查
String name = null;
// 编译通过,但运行直接崩溃:NullPointerException
System.out.println(name.length());
Kotlin 代码(编译期直接报错,杜绝空指针)
// 1. 非空类型(默认):不能赋值为 null,编译报错
var name: String = null // 报错:Null can not be a value of a non-null type String
// 2. 可空类型(必须加 ? 声明)
var name: String? = null
// 直接调用会编译报错,必须做非空判断
name.length // 报错:Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver
// 安全调用:如果为 null,直接返回 null,不崩溃
println(name?.length) // 输出:null
总结:Kotlin 空安全让空指针异常几乎消失,Java 全靠手动判空。
二、语法简洁度(Kotlin 代码量少 40%+)
Kotlin 省略了 Java 大量冗余语法:分号、new 关键字、getter/setter、构造方法等。
1. 定义变量
Java
// 必须写类型、分号
String name = "张三";
final int age = 20; // 常量
Kotlin
// var 可变变量,val 只读变量(等价Java final)
var name = "张三" // 自动推导类型,无需分号
val age = 20
2. 定义实体类(Java 10行 = Kotlin 1行)
Java(写半天 getter/setter/构造方法)
public class User {
private String name;
private int age;
// 构造方法
public User(String name, int age) {
this.name = name;
this.age = age;
}
// getter/setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
Kotlin(一行搞定,自动生成所有方法)
// 自动生成:构造方法、getter、setter、equals、toString 等
data class User(val name: String, val age: Int)
总结:Kotlin 大幅减少样板代码,开发效率更高。
三、方法定义与 Lambda 表达式
1. 基础方法
Java
// 必须写返回值、修饰符、分号
public int add(int a, int b) {
return a + b;
}
Kotlin
// 自动推导返回值,单表达式直接省略花括号和 return
fun add(a: Int, b: Int) = a + b
2. Lambda 简化(集合遍历)
Java
List<Integer> list = Arrays.asList(1,2,3);
// 冗余语法
list.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer i) {
System.out.println(i);
}
});
Kotlin
val list = listOf(1,2,3)
list.forEach { println(it) } // it 代表当前元素,极简
四、默认参数与具名参数(Kotlin 独有)
Java 没有默认参数,必须写方法重载,代码冗余;Kotlin 直接支持默认参数。
Java(方法重载)
public void printInfo(String name, int age) { ... }
public void printInfo(String name) { printInfo(name, 18); } // 重载
public void printInfo() { printInfo("匿名", 18); } // 重载
Kotlin(默认参数)
// 直接给参数赋默认值,调用时可传参也可不传
fun printInfo(name: String = "匿名", age: Int = 18) {
println("姓名:$name,年龄:$age")
}
// 调用:自由组合参数
printInfo() // 输出:姓名:匿名,年龄:18
printInfo("张三") // 输出:姓名:张三,年龄:18
printInfo(age = 20) // 具名参数,指定传哪个
五、扩展函数(Kotlin 独有,超级实用)
Kotlin 可以不修改原类,直接给现有类添加新方法;Java 必须继承类或写工具类。
示例:给 String 类添加「获取字数」方法
Java(必须写工具类)
public class StringUtils {
public static int getWordCount(String str) {
return str.length();
}
}
// 调用:繁琐
StringUtils.getWordCount("hello");
Kotlin(直接扩展 String 类)
// 给 String 类扩展方法,全局可用
fun String.getWordCount() = this.length
// 调用:像调用原生方法一样自然
"hello".getWordCount() // 输出:5
场景:给系统类、第三方库添加功能,无需继承,无侵入性。
六、智能类型转换(Kotlin 独有)
Java 判空后必须强制类型转换;Kotlin 编译器自动识别,无需强转。
Java
Object obj = "abc";
if (obj instanceof String) {
// 必须手动强转
String str = (String) obj;
System.out.println(str.length());
}
Kotlin
val obj: Any = "abc"
if (obj is String) {
// 编译器自动转换为 String,无需强转
println(obj.length)
}
七、静态成员与顶层函数
Java 用 static 定义静态成员;Kotlin 没有 static 关键字,用伴生对象/顶层函数替代。
Java
public class Utils {
public static void show() {
System.out.println("静态方法");
}
}
// 调用
Utils.show();
Kotlin
// 方式1:伴生对象(等价Java static)
class Utils {
companion object {
fun show() = println("伴生对象方法")
}
}
// 方式2:顶层函数(直接写在文件里,全局调用)
fun show() = println("顶层函数")
// 调用(和静态方法一样)
Utils.show()
show()
八、区间与循环(Kotlin 更直观)
Java
// 遍历 1-10
for (int i = 1; i <= 10; i++) { ... }
Kotlin
// 区间表达式:1..10 代表 1到10
for (i in 1..10) { ... }
// 倒序、步长
for (i in 10 downTo 1 step 2) { ... }
九、异常处理
Java 必须捕获受检异常(Checked Exception);Kotlin 取消了受检异常,更灵活。
Java
// 必须 try-catch 或 throws,否则编译报错
public void readFile() throws IOException {
FileReader reader = new FileReader("test.txt");
}
Kotlin
// 无需强制捕获,编译通过,运行时异常正常处理
fun readFile() {
val reader = FileReader("test.txt")
}
十、协程(Kotlin 独有,替代 Java 线程)
Kotlin 原生支持协程,轻量级异步编程,替代 Java 的 Thread/AsyncTask/回调地狱。
Java(异步回调,代码嵌套混乱)
new Thread(() -> {
// 耗时操作
String result = requestApi();
// 切回主线程
runOnUiThread(() -> textView.setText(result));
}).start();
Kotlin(协程,线性代码写异步)
// 极简异步,无回调嵌套
lifecycleScope.launch {
// 耗时操作(自动切子线程)
val result = requestApi()
// 自动切主线程
textView.text = result
}
总结:Kotlin 协程让异步代码简洁、易读、易维护,Java 线程方案臃肿易出错。
核心区别速查表
| 特性 | Java | Kotlin |
|---|---|---|
| 空安全 | 无,易空指针 | 编译期检查,杜绝空指针 |
| 代码量 | 冗余,样板代码多 | 简洁,少 40%+ 代码 |
| 扩展函数 | 不支持 | 原生支持,无侵入扩展 |
| 智能转换 | 必须手动强转 | 自动类型转换 |
| 默认参数 | 不支持,需重载 | 原生支持 |
| 协程 | 无,依赖线程 | 原生支持,轻量级异步 |
| 实体类 | 需手写 getter/setter | 一行 data class 搞定 |
| Lambda | 语法繁琐 | 极简,支持 it 关键字 |
总结
- 兼容性:Kotlin 完全兼容 Java,可混合开发,无缝迁移;
- 安全性:Kotlin 空安全、智能转换大幅降低崩溃率;
- 效率:Kotlin 语法极简、扩展函数、协程让开发速度翻倍;
- 定位:Java 是老牌严谨语言,Kotlin 是现代化高效语言,现在主流开发优先选 Kotlin。