kotlin和java的区别

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 关键字

总结

  1. 兼容性:Kotlin 完全兼容 Java,可混合开发,无缝迁移;
  2. 安全性:Kotlin 空安全、智能转换大幅降低崩溃率;
  3. 效率:Kotlin 语法极简、扩展函数、协程让开发速度翻倍;
  4. 定位:Java 是老牌严谨语言,Kotlin 是现代化高效语言,现在主流开发优先选 Kotlin
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容