Java vs Kotlin 在实际开发中的主要区别与面试题总结
随着 Google 官方宣布 Kotlin 成为 Android 首选语言,越来越多的开发者开始从 Java 转向 Kotlin。虽然两者都运行在 JVM 上,但在语法、特性和开发体验上有明显差异。本文将结合实例,详细分析 Java 与 Kotlin 的区别,并附上常见面试题总结,帮助大家更好地理解和应用。
1. 空安全(Null Safety)
在 Java 中,NullPointerException (NPE)
是最常见的运行时错误。
Java 写法
java
public class User {
private String name;
public String getName() {
return name;
}
}
public class Test {
public static void main(String[] args) {
User user = new User();
System.out.println(user.getName().length()); // 可能抛出 NPE
}
}
Kotlin 写法
kotlin
class User(var name: String?)
fun main() {
val user = User(null)
println(user.name?.length ?: "没有名字") // 安全调用
}
✅ 区别总结
- Java 需要手动判空。
- Kotlin 编译期提供空安全检查,
?.
、?:
、!!
避免大部分 NPE。
2. 数据类(Data Class)
在 Java 中,定义一个 POJO 需要写构造方法、getter/setter、equals、hashCode、toString。
Java 写法
java
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + "}";
}
}
Kotlin 写法
kotlin
data class User(val name: String, val age: Int)
fun main() {
val user = User("Tom", 20)
println(user) // 自动生成 toString: User(name=Tom, age=20)
}
✅ Kotlin data class
自动生成 equals
、hashCode
、toString
等方法,更简洁。
3. Lambda 表达式与函数式编程
Java 写法
java
List<String> list = Arrays.asList("a", "b", "c");
list.forEach(s -> System.out.println(s.toUpperCase()));
Kotlin 写法
kotlin
val list = listOf("a", "b", "c")
list.forEach { println(it.uppercase()) }
✅ Kotlin 语法更简洁,支持自然的函数式写法。
4. 扩展函数(Extension Function)
Java 写法(工具类)
java
public class StringUtils {
public static String lastChar(String str) {
return str.substring(str.length() - 1);
}
}
String result = StringUtils.lastChar("Hello");
Kotlin 写法(扩展函数)
kotlin
fun String.lastChar(): Char = this[this.length - 1]
fun main() {
println("Hello".lastChar()) // o
}
✅ Kotlin 支持扩展函数,Java 必须写工具类。
5. 协程 vs 线程
Java 异步
java
CompletableFuture.supplyAsync(() -> {
return "Hello";
}).thenAccept(result -> {
System.out.println(result);
});
Kotlin 协程
kotlin
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
val result = async { "Hello" }.await()
println(result)
}
}
✅ Kotlin 协程更轻量,写法更接近同步逻辑。
6. 默认参数与命名参数
Java 写法
java
public void showMessage(String text) {
showMessage(text, false);
}
public void showMessage(String text, boolean isImportant) {
System.out.println((isImportant ? "[!]" : "") + text);
}
Kotlin 写法
kotlin
fun showMessage(text: String, isImportant: Boolean = false) {
println((if (isImportant) "[!]" else "") + text)
}
fun main() {
showMessage("Hello")
showMessage("Warning!", isImportant = true)
}
✅ Kotlin 支持默认参数和命名参数,减少重载方法。
7. Android 开发中的差异
Java 写法
java
TextView tv = findViewById(R.id.textView);
tv.setText("Hello");
Kotlin 写法
kotlin
binding.textView.text = "Hello"
✅ Kotlin 与 ViewBinding / Compose 结合,简洁高效。
8. 常见面试题对比
Q1. Kotlin 的 ==
和 ===
有什么区别?
==
比较内容(等价于 Java.equals()
)。===
比较引用地址(等价于 Java==
)。
kotlin
val a = String("Hello".toCharArray())
val b = String("Hello".toCharArray())
println(a == b) // true
println(a === b) // false
Q2. Kotlin 协程和 Java 线程区别?
- Java 线程:重量级,数量多时开销大。
- Kotlin 协程:轻量级,挂起不会阻塞线程,可同时运行上万个。
kotlin
fun main() = runBlocking {
repeat(10000) {
launch {
delay(1000)
println("协程 $it 完成")
}
}
}
Q3. Kotlin 和 Java 在性能上有区别吗?
- 本质性能一致(同为 JVM 字节码)。
- Kotlin 有少量包装开销,但
inline
可优化。 - 在 Android 中,性能差异可以忽略。
Q4. lateinit
vs lazy
lateinit
:延迟初始化,var
,适合依赖注入。lazy
:懒加载,val
,第一次访问时才初始化。
kotlin
lateinit var name: String
val config: String by lazy { "加载配置" }
Q5. Kotlin 在 Android 的地位?
- Java:早期唯一语言,老项目仍大量使用。
- Kotlin:Google 官方推荐语言,Compose、协程、KTX 优先支持。
👉 招聘趋势:Kotlin 是主流,但 Java 依然是基础。
总结
特性 | Java | Kotlin |
---|---|---|
空安全 | 手动判空 | 编译期检查,?. 、?: |
数据类 | 样板代码多 | 一行 data class |
Lambda | Java 8 引入 | 更简洁 |
扩展函数 | 不支持 | 原生支持 |
异步 | Future/Callback | 协程 |
参数 | 方法重载 | 默认参数 + 命名参数 |
Android | findViewById |
ViewBinding / Compose |
👉 结论
- Kotlin 并非要取代 Java,而是让 JVM 生态更现代化。
- 在 Android 开发中,Kotlin 的简洁性、协程、扩展函数等特性,让它成为首选语言。
- 面试中需重点掌握 Kotlin 的语法糖、协程、空安全等特性,以及与 Java 的差异。