news 2026/4/16 18:12:21

Kotlin和Java区别,零基础入门到精通,收藏这篇就够了

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kotlin和Java区别,零基础入门到精通,收藏这篇就够了

前段时间,面试的时候,突然问到我Kotlin和Java的区别,一下子把我问懵逼了,确实没遇到问这个的,想了下,说了下Kotlin的编译时空检查机制,代码更简洁,很多封装好的API可以直接调用,Kotlin有Jetpack全家桶,有协程,有lateinit和by lazy懒加载机制等等,后面着重问我协程去了,但是我知道我也有很多没有答上。

今天自己做个总结:

1. 语法简洁性

🔹Kotlin 代码通常比 Java 更简洁,减少了模板代码(boilerplate)。

🔸Java 示例(获取 List 的大小并遍历):

List<String> list = Arrays.asList("A", "B", "C"); for (String item : list) { System.out.println(item); }

Kotlin

val list = listOf("A", "B", "C") list.forEach { println(it) }

2. Null 安全

🔹Java 中NullPointerException(NPE) 是常见错误

String name = null; System.out.println(name.length()); // 运行时崩溃:NullPointerException

🔹Kotlin 通过可空类型和安全调用避免 NPE:

var name: String? = null println(name?.length) // 安全调用,避免 NPE
  • ?允许null
  • ?.安全访问,避免 NPE
  • !!强制非空,可能引发异常,尽量少用。

3. 数据类 (Data Class)

🔹Java 需要大量代码来定义 POJO(数据类):

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; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User{name='" + name + "', age=" + age + "}"; } }

🔹Kotlin 只需一行代码:

data class User(val name: String, val age: Int)
  • 自动生成getter/settertoString()equals()hashCode()

data class的详细介绍和区别:Serializable,Parcelable和data class的区别_data class parcelable-CSDN博客文章浏览阅读992次,点赞24次,收藏26次。序列化是将对象的状态(属性数据)转换为字节流或其他可存储或传输的格式的过程。主要作用存储:将对象保存到文件或数据库中。传输:在网络中传输对象,比如在客户端与服务器之间传递数据。缓存:将对象转化为可恢复的格式,便于后续恢复使用。序列化后7. 什么是反序列化(Deserialization)?反序列化是将序列化后的字节流(或存储格式)重新转换回原始对象的过程。主要作用从存储或传输的格式中重建对象。恢复数据到应用中,便于程序继续使用。8.序列化与反序列化的用途网络传输。_data class parcelablehttps://blog.csdn.net/LoveFHM/article/details/143875848?spm=1001.2014.3001.5502

4. 扩展函数 (Extension Functions)

🔹Java 需要创建工具类来扩展已有类的功能

public class StringUtils { public static String capitalize(String str) { return str.substring(0, 1).toUpperCase() + str.substring(1); } } String result = StringUtils.capitalize("hello");

🔹Kotlin 直接扩展类的方法

fun String.capitalizeFirst(): String = this.replaceFirstChar { it.uppercaseChar() } val result = "hello".capitalizeFirst()

5. 函数式编程

Kotlin 支持高阶函数Lambda 表达式,让代码更优雅。

🔹Java 的匿名内部类:

button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { System.out.println("Clicked"); } });

🔹Kotlin 的 Lambda 表达式:

button.setOnClickListener { println("Clicked") }

6. 协程 vs. Java 线程

🔹Java 使用线程管理并发,代码较复杂:

new Thread(new Runnable() { @Override public void run() { System.out.println("线程运行中..."); } }).start();

🔹Kotlin 协程更高效,且不会阻塞线程

GlobalScope.launch { println("协程运行中...") }
  • 协程比 Java 线程更轻量,可以高效处理并发任务。管理起来也很轻松,可以和生命周期绑定

Kotlin 协程(一)协程的定义及基础使用_kotlin 协程使用-CSDN博客

7. Smart Cast(智能类型转换)

🔹Java 需要显式类型转换

Object obj = "Hello"; if (obj instanceof String) { String str = (String) obj; // 需要手动转换 }

🔹Kotlin 自动类型转换

val obj: Any = "Hello" if (obj is String) { println(obj.length) // Kotlin 自动转换,无需 `(String) obj` }
  • 智能类型推断:Kotlin 可以自动推断变量类型,无需显式声明,如val name = "Lee"而不需要String name = "Lee";

8.when取代switch

🔹Javaswitch-case语法繁琐

🔹Kotlinwhen语法更简洁,when更直观,支持范围判断表达式返回值

9. 类默认final

  • Java 类默认是open的,可以继承,除非加final

  • Kotlin 类默认final,必须显式open允许继承

10.总结对比表

特性JavaKotlin
语法冗长简洁
Null 安全可能导致 NPE避免 NPE
数据类需要手写getter/setterdata class自动生成
扩展函数需要工具类直接扩展
高阶函数需要匿名类直接支持 Lambda
并发线程(较重)协程(轻量)
类型转换需手动转换自动Smart Cast
switch 语法switch-casewhen
类默认行为默认可继承默认final

其他的:

11. Kotlin的懒加载

在 Kotlin 中,懒加载(Lazy Initialization)主要有两种方式:

  1. lazy适用于 val 只读变量
  2. lateinit适用于 var 可变变量

Kotlin by lazy和lateinit的使用及区别_kotlin by lazy 与lateinit-CSDN博客

12.单例模式

传统的懒汉式(lazy + @Volatile + synchronized)

class Singleton private constructor() { companion object { @Volatile private var instance: Singleton? = null fun getInstance(): Singleton { return instance ?: synchronized(this) {//第一次空检查 instance ?: Singleton().also { instance = it }//第二次空检查 } } } }

这里的双重检查:

  1. 第一次检查 (instance ?:)

    • 避免不必要的同步开销。
    • 如果已经初始化,直接返回,避免进入synchronized代码块,提高性能。
  2. 同步代码块内部的第二次检查 (instance ?:)

    • 由于多个线程可能同时通过第一次检查进入synchronized,所以需要再次检查instance是否为null,防止重复创建实例。

为什么要用@Volatile

  • @Volatile防止指令重排序(保证可见性)。

  • 如果不加@Volatile,可能会发生 部分初始化(对象创建未完成,别的线程就拿到不完整的实例)。

  • 避免可能的 NullPointerException(NPE)。

lazy懒加载

class Singleton private constructor() { companion object { val instance: Singleton by lazy { Singleton() } } }
  • 线程安全(lazy默认是LazyThreadSafetyMode.SYNCHRONIZED)。
  • 更简洁,不需要synchronized@Volatile

最简单的单例

object Singleton { fun doSomething() { println("Hello from Singleton!") } }
  • 线程安全,在 Kotlin 中,object关键字天然是线程安全的,因为它的初始化由 JVM类加载机制(Class Loading Mechanism)保证,由于 JVM类加载过程是线程安全的,所以object也是线程安全的!

  • 写法简单

  • 类加载时就初始化(饿汉式)

🔹 双重检查锁的 Java 代码

public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { // 第一次检查(避免不必要的同步) synchronized (Singleton.class) { // 线程同步 if (instance == null) { // 第二次检查(确保只创建一次) instance = new Singleton(); } } } return instance; } }

13.kotlin的内联函数

  • Kotlin 允许使用inline关键字,将高阶函数的函数调用直接替换为函数体代码,从而减少不必要的对象创建和额外的函数调用开销。
  • 主要作用:
    1. 避免高阶函数带来的 Lambda 表达式性能损耗。
    2. 允许crossinlinenoinline修饰参数,进一步控制内联行为。
inline fun execute(action: () -> Unit) { println("Before action") action() println("After action") } fun main() { execute { println("Executing task...") } }

等效于:

fun main() { println("Before action") println("Executing task...") println("After action") }

execute()方法的 Lambda 参数直接被展开,避免了额外的函数调用。

优点

  • 减少 Lambda 运行时开销(避免创建Function对象)
  • 提升代码执行效率
  • 支持非局部返回(可以使用return直接从调用函数返回)

注意事项

  • 避免过度使用,内联会导致代码膨胀,影响 APK 体积和方法数量。
  • 仅适用于小型 Lambda,对于大函数,内联会增加代码量而不是优化性能。

来个具体点的例子:

kotlin:

inline fun measureExecutionTime( crossinline beforeStart: () -> Unit, block: () -> Unit, crossinline afterEnd: () -> Unit ) { beforeStart() val startTime = System.currentTimeMillis() block() val endTime = System.currentTimeMillis() afterEnd() println("Execution Time: ${endTime - startTime} ms") } fun main() { measureExecutionTime( beforeStart = { println("Starting execution...") }, block = { Thread.sleep(500) // 模拟耗时操作 println("Executing task...") }, afterEnd = { println("Execution completed.") } ) }

java代码:

public class Main { public static void measureExecutionTime(Runnable beforeStart, Runnable block, Runnable afterEnd) { beforeStart.run(); long startTime = System.currentTimeMillis(); block.run(); long endTime = System.currentTimeMillis(); afterEnd.run(); System.out.println("Execution Time: " + (endTime - startTime) + " ms"); } public static void main(String[] args) { measureExecutionTime( () -> System.out.println("Starting execution..."), () -> { try { Thread.sleep(500); // 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Executing task..."); }, () -> System.out.println("Execution completed.") ); } }

Java 代码中:

  • Java 需要为Runnable创建匿名内部类或 Lambda 对象,每次调用时都需要分配额外的内存。

  • Runnable作为参数传递,执行block.run(),涉及额外的函数调用

  • Java 的 Lambda 不能访问return语句,只能使用return结束Runnable的逻辑。

Kotlin 内联:

  • inline使得measureExecutionTime不会创建任何 Lambda 对象,它的调用会被直接替换为代码块,消除对象分配和函数调用的开销。

  • 直接展开代码,避免额外的函数调用。

  • 支持非局部返回(普通 Lambda 不能直接return退出measureExecutionTime,但inline可以)。

14. Any vs Object

在 Kotlin 中,Any是所有非null类型的超类,而在 Java 中,Object是所有类的超类。但它们并不完全等价,主要区别如下:

1.Any不包含null,而Object可以

  • 在 Kotlin 中,Any不能存储null,如果需要允许null,必须使用Any?

  • Java 的Object默认可以存储null

2.Any只有equalshashCodetoString

  • Kotlin 的Any只包含equals()hashCode()toString(),没有wait()notify()这些Object的方法。

  • Java 的Object还提供了wait()notify()clone()线程相关的方法。

3.Any不能直接用于 Java 互操作

在 Java 方法中,如果你需要一个Object,KotlinAny不能直接替代它,必须显式转换为Object

5.AnyUnitNothing的超类,而Object不是

在 Kotlin,Unit(等价于 Javavoid)和Nothing也是Any的子类

15.智能类型转换(Smart Casts)

概念

  • Kotlin 编译器可以自动推断类型,避免手动类型转换 (cast),提升代码可读性和安全性。
  • 只要 Kotlin 确定变量不会改变类型,就可以自动转换。

java代码:

void printLength(Object obj) { if (obj instanceof String) { String str = (String) obj; // 需要手动转换 System.out.println(str.length()); } }

kotlin代码:

fun printLength(obj: Any) { if (obj is String) { // 这里 obj 自动转换为 String println(obj.length) // 直接使用,不需要手动转换 } }

强制转换(asas?),其中as?安全转换,避免ClassCastException

val obj: Any = 123 val str: String? = obj as? String // 转换失败返回 null println(str) // null

Java开发的就业市场正在经历结构性调整,竞争日益激烈

传统纯业务开发岗位(如仅完成增删改查业务的后端工程师)的需求,特别是入门级岗位,正显著萎缩。随着企业技术需求升级,市场对Java人才的要求已从通用技能转向了更深入的领域经验(如云原生、微服务)或前沿的AI集成能力。这也导致岗位竞争加剧,在一、二线城市,求职者不仅面临技术内卷,还需应对学历与项目经验的高门槛。

大模型为核心的AI领域正展现出前所未有的就业热度与人才红利

2025年,AI相关新发岗位数量同比激增543%,单月增幅最高超过11倍,大模型算法工程师位居热门岗位前列。行业顶尖人才的供需严重失衡,议价能力极强,跳槽薪资涨幅可达30%-50%。值得注意的是,市场并非单纯青睐算法研究员,而是急需能将大模型能力落地于复杂业务系统的工程人才。这使得具备企业级架构思维和复杂系统整合经验的Java工程师,在向“Java+大模型”复合人才转型时拥有独特优势,成为企业竞相争夺的对象,其薪资天花板也远高于传统Java岗位。

说真的,这两年看着身边一个个搞Java、C++、前端、数据、架构的开始卷大模型,挺唏嘘的。大家最开始都是写接口、搞Spring Boot、连数据库、配Redis,稳稳当当过日子。

结果GPT、DeepSeek火了之后,整条线上的人都开始有点慌了,大家都在想:“我是不是要学大模型,不然这饭碗还能保多久?”

先给出最直接的答案:一定要把现有的技术和大模型结合起来,而不是抛弃你们现有技术!掌握AI能力的Java工程师比纯Java岗要吃香的多。

即使现在裁员、降薪、团队解散的比比皆是……但后续的趋势一定是AI应用落地!大模型方向才是实现职业升级、提升薪资待遇的绝佳机遇!

如何学习AGI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版CSDN大礼包:《AGI大模型学习资源包》免费分享**

一、2025最新大模型学习路线

一个明确的学习路线可以帮助新人了解从哪里开始,按照什么顺序学习,以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛,没有明确的学习路线可能会导致新人感到迷茫,不知道应该专注于哪些内容。

我们把学习路线分成L1到L4四个阶段,一步步带你从入门到进阶,从理论到实战。

L1级别:AI大模型时代的华丽登场

L1阶段:我们会去了解大模型的基础知识,以及大模型在各个行业的应用和分析;学习理解大模型的核心原理,关键技术,以及大模型应用场景;通过理论原理结合多个项目实战,从提示工程基础到提示工程进阶,掌握Prompt提示工程。

L2级别:AI大模型RAG应用开发工程

L2阶段是我们的AI大模型RAG应用开发工程,我们会去学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。

L3级别:大模型Agent应用架构进阶实践

L3阶段:大模型Agent应用架构进阶实现,我们会去学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造我们自己的Agent智能体;同时还可以学习到包括Coze、Dify在内的可视化工具的使用。

L4级别:大模型微调与私有化部署

L4阶段:大模型的微调和私有化部署,我们会更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调;并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。

整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握;而L3 L4更多的是通过项目实战来掌握大模型的应用开发,针对以上大模型的学习路线我们也整理了对应的学习视频教程,和配套的学习资料。

二、大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

三、大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

四、大模型项目实战

学以致用,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

五、大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版CSDN大礼包:《AGI大模型学习资源包》免费分享

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 12:39:39

状态管理:Flutter 为什么走上了和前端一样的“百家争鸣”?

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

作者头像 李华
网站建设 2026/4/16 10:57:12

GESP Python 编程一级教材之 13 掌握模块的导入方法(教程含历年试题解析)

系列文章 《GESP系列教程之 什么是GESP?》 《GESP 认证标准之 Python 编程一级标准(考试大纲与要求含考试真题)》 《GESP 认证标准之 Python 编程二级标准(考试大纲与要求含考试真题)》 《GESP 认证标准之 Python 编程三级标准(考试大纲与要求含考试真题)》 《GESP …

作者头像 李华
网站建设 2026/4/16 14:26:09

多智能体实战指南:9种模式打造高效AI应用

想要构建一个智能体应用&#xff0c;最重要的是什么&#xff1f;可能很多人首先会想到要选择一个性能强大的大模型。 这个回答没错&#xff0c;毕竟当前的LLM Based Agent哪能缺少LLM的支撑。但事实却是&#xff0c;很多基于先进大模型构建的智能体没能体现出应用效果&#xff…

作者头像 李华
网站建设 2026/4/16 12:35:17

微信小程序 PHP_uniapp的智能购物助手与价格比较系统的设计与实现_77607w0u

摘要 该研究聚焦于基于微信小程序的智能购物助手与价格比较系统的设计与实现&#xff0c;采用PHP后端与UniApp前端框架相结合的技术方案。系统旨在解决用户在多平台购物时面临的比价效率低、信息分散等问题&#xff0c;通过智能化的商品检索与价格分析功能&#xff0c;提升用户…

作者头像 李华
网站建设 2026/4/16 10:55:07

OddAgent:一个通用的意图、指令识别框架

想自己动手来手搓一个完全属于你自己的“小爱同学”、“小艺”吗&#xff1f;如果有你这么一个想法&#xff0c;而又不知道该如何开始的话&#xff0c;那么OddAgent项目可以成为你非常容易上手的开源项目。 本来这个功能是小落同学在2024年初就已经支持&#xff0c;由于前阵子…

作者头像 李华