作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Gabriel是一名高级Android工程师,拥有8年用Kotlin和Java从头开始构建应用程序的经验, 并促进两种语言之间的转换. 加布里埃尔曾开发过价值数百万美元的应用程序,并在HBO和雅虎等公司拥有行业经验.
的确,Java在Android大战中败给了 Kotlin这是b谷歌目前的首选语言,因此更适合新的移动应用程序. 但是Kotlin和Java都提供了许多作为通用语言的优势, 对于开发人员来说,理解语言差异是很重要的, 用于从Java迁移到Kotlin等目的. In this article, 我们将分解Kotlin和Java的异同,以便您可以做出明智的决定,并在两者之间无缝切换.
实际上,从高级的角度来看,这两种语言有很多共同之处. Kotlin和Java都运行在 Java虚拟机(JVM) 而不是直接构建到本机代码. 这两种语言可以很容易地相互调用:您可以从Kotlin调用Java代码,也可以从Java调用Kotlin代码. Java 可用于服务器端应用程序,数据库,web前端应用程序, embedded systems 企业应用程序、移动应用程序等等. Kotlin同样是通用的:它针对JVM、Android、JavaScript和java Kotlin/Native,也可用于服务器端、web和桌面开发.
Java是一种比Kotlin成熟得多的语言,它在1996年发布了第一个版本. Though Kotlin 1.在2016年,Kotlin很快成为了官方首选语言 安卓开发 in 2019. 然而,在Android之外,没有人建议用Kotlin代替Java.
Year | Java | Kotlin |
---|---|---|
1995–2006 | JDK Beta, JDK 1.0, JDK 1.1, J2SE 1.2, J2SE 1.3, J2SE 1.4, J2SE 5.0, Java SE 6 | N/A |
2007 | 项目织机首次提交 | N/A |
2010 | N/A | Kotlin开发开始了 |
2011 | Java SE 7 | Kotlin项目宣布 |
2012 | N/A | Kotlin开源 |
2014 | Java SE 8 (LTS) | N/A |
2016 | N/A | Kotlin 1.0 |
2017 | Java SE 9 | Kotlin 1.2; Kotlin support for Android announced |
2018 | Java SE 10、Java SE 11 (LTS) | Kotlin 1.3 (coroutines) |
2019 | Java SE 12, Java SE 13 | Kotlin 1.4 (interoperability for Objective-C and Swift); Kotlin announced as Google’s preferred language for developers |
2020 | Java SE 14, Java SE 15 | N/A |
2021 | Java SE 16、Java SE 17 (LTS) | Kotlin 1.5, Kotlin 1.6 |
2022 | Java SE 18, JDK 19 | Kotlin 1.7 (Kotlin K2编译器的alpha版本),Kotlin 1.8 |
2023 | Java SE 20, Java SE 21, JDK 20, JDK 21 | Kotlin 1.9 |
2024 | Java SE 22 (scheduled) | Kotlin 2.0 (potentially) |
在详细介绍Kotlin和Java的特性之前, 我们将检查它们的性能和内存消耗,因为这些因素通常是开发人员和客户的重要考虑因素.
Kotlin, Java, 以及其他JVM语言, 虽然不相等, 在性能方面是否相当相似, 至少与GCC或Clang等其他编译器家族的语言相比是这样. JVM最初是在20世纪90年代针对资源有限的嵌入式系统设计的. 相关的环境要求导致了两个主要的限制:
具有类似的编译过程和运行时环境, Kotlin和Java的性能差异很小,这是因为它们的特性不同. For example:
InvokeDynamic
,提高性能.现在让我们转向记忆. 在理论上,对基类型(i.e.(Kotlin的实现)需要比原始数据类型(如Kotlin)更多的分配.e., Java的实现). 然而,在实践中,Java的字节码使用 自动装箱和拆箱 调用来处理对象,如果过多使用,可能会增加计算开销. For example, Java’s String.format
method 只接受对象作为输入,因此格式化Java int
will box it in an Integer
对象之前调用 String.format
.
总的来说,Java和Kotlin在性能和内存方面没有明显的差异. You may examine online benchmarks 哪些在微基准测试中显示了微小的差异, 但这些不能推广到一个完整的生产应用程序的规模.
Kotlin和Java有核心的相似之处,但是每种语言都提供了不同的、独特的特性. 自从Kotlin成为b谷歌首选的Android开发语言以来, 我发现扩展函数和显式空性是最有用的特性. 另一方面,在使用Kotlin时,我最想念的Java特性是 protected
关键字和三元运算符.
让我们更详细地分析一下Kotlin和Java中可用的特性. 您可以跟随我的示例,使用Kotlin Playground或Java编译器来获得更实际的学习方法.
Feature | Kotlin | Java | Description |
---|---|---|---|
扩展函数 | Yes | No |
允许您扩展类或接口的新功能,如添加属性或方法,而无需创建新类:
|
Smart casts | Yes | No |
跟踪内部情况
if 语句,安全自动强制转换:
Kotlin还提供了安全和不安全的强制转换操作符:
|
Inline functions | Yes | No | 通过内联函数代码(将其复制到调用站点)减少内存开销并提高速度: Inline fun示例() . |
对委托的本地支持 | Yes | No | |
Type aliases | Yes | No | 为现有类型提供缩短或自定义名称, 包括函数和内部类或嵌套类的: typealias ShortName = LongNameExistingType . |
私人领域 | No | Yes | Offers protected 和默认(也称为 package-private )修饰语,除了 public and private modifiers. Java has all four access modifiers而Kotlin则失踪了 protected 和默认修饰符. |
Ternary operator | No | Yes |
用更简单、更易读的代码替换if/else语句:
|
隐式扩展转换 | No | Yes |
允许从较小的数据类型自动转换为较大的数据类型:
|
已检查的异常 | No | Yes |
类中捕获异常的方法
throws 关键字或用try-catch块处理异常.注意:受控异常旨在鼓励开发人员设计健壮的软件. However, 他们可以创建样板代码, 使重构变得困难, 并导致错误处理不当. 这个特性是有利还是不利取决于开发人员的偏好.
|
有一个主题我故意从这个表中排除:Kotlin与Java的空安全性. 这个主题需要对Kotlin和Java进行更详细的比较.
在我看来,非空性是Kotlin最伟大的特性之一. 此功能节省了时间,因为开发人员不必处理 NullPointerException
s (which are RuntimeException
s).
在Java中,默认情况下,您可以分配 null
为任意变量赋值:
String x = null;
//运行此代码会抛出NullPointerException
try {
System.out.println("第一个字符:" + x.charAt(0));
} catch (NullPointerException) {
System.out.println(“抛出NullPointerException!");
}
另一方面,在Kotlin中,我们有两个选择,使变量为空或非为空:
var nonnullablennumber: Int = 1
//这一行抛出编译时错误,因为你不能赋空值
nonnullablennumber = null
var nullablennumber: Int? = 2
//这一行不会抛出错误,因为我们使用了一个可空变量
nullablennumber = null
默认情况下,我使用非空变量, and minimize the use of nullable variables for best practices; these Kotlin versus Java examples are meant to demonstrate differences in the languages. Kotlin初学者应该避免毫无目的地将变量设置为可空的陷阱(在将Java代码转换为Kotlin时也可能发生这种情况)。.
然而,在Kotlin中有一些情况下你会使用可空变量:
Scenario | Example |
---|---|
您正在搜索列表中不存在的项(通常在处理数据层时). |
|
您希望在运行时初始化变量,使用 lateinit . |
|
我对过度使用感到内疚 lateinit
变量,当我刚开始使用Kotlin时. 最后,我几乎完全不再使用它们了,除了定义的时候 view bindings and 变量注射 in Android:
@Inject //在Hilt库中,这是自动初始化的
lateinit var manager: SomeManager
lateinit var viewBinding: viewBinding
fun onCreate() {// i.e.Android的onCreate
binding = ActivityMainBinding.膨胀(layoutInflater, parentView, true)
// ...
}
On the whole, 与Java相比,Kotlin中的null安全性提供了额外的灵活性和改进的开发人员体验.
每种语言都有其独特的特点, Kotlin和Java也共享许多特性, 为了在两种语言之间进行转换,有必要了解它们的特点. 让我们来看看在Kotlin和Java中不同操作的四个常见概念:
Feature | Java | Kotlin |
---|---|---|
数据传输对象(dto) |
Java记录,它保存有关数据或状态的信息,并包括
toString , equals , and hashCode 自Java SE 15以来,默认情况下已可用:
|
Kotlin数据类的功能类似于Java记录,使用
toString , equals , and copy 方法:
|
Lambda表达式 |
Java lambda表达式(从Java 8开始可用)遵循一个简单的
parameter -> expression 语法,多个参数使用圆括号: (parameter1, parameter2) -> { code } :
|
Kotlin lambda表达式遵循该语法
{ parameter1, parameter2 -> code } 并且总是被花括号包围:
|
Java线程使并发成为可能 java.util.concurrency 包允许通过它的实用程序类实现简单的多线程. The Executor and ExecutorService classes 特别有利于并发吗. (Project Loom 还提供轻量级线程.) | Kotlin coroutines, from the kotlinx.coroutines 库,促进并发性,并为多线程包含一个单独的库分支. The memory manager in Kotlin 1.7.20及以后的版本减少了以前对开发者在iOS和Android之间迁移的并发性和多线程的限制. | |
类中的静态行为 |
Java静态成员促进了类实例之间的代码共享,并确保只创建一个项目的单一副本. The
static 关键字可以应用于变量、函数、块等:
|
Kotlin 同伴的对象 在类中提供静态行为,但语法不那么简单:
|
当然,Kotlin和Java也有不同的语法. 讨论每个语法差异超出了我们的范围, 但是考虑循环应该会让你对整体情况有一个概念:
Loop Type | Java | Kotlin |
---|---|---|
for , using in
|
|
|
for , using until
|
|
|
forEach |
|
|
while |
|
|
An 深入了解Kotlin的特性 将有助于Kotlin和Java之间的转换.
我们研究了在通用上下文中选择Kotlin还是Java时需要考虑的许多重要因素. However, 如果不解决房间里的大象:Android,那么Kotlin与Java的对比分析是不完整的. 你在做什么? Android应用程序从头开始 想知道你应该用Java还是Kotlin? 选择Kotlin,谷歌首选的Android语言,毫无疑问.
然而,这个问题对于现有的Android应用程序来说是没有意义的. 根据我和很多客户打交道的经验, 还有两个更重要的问题是:你们如何对待科技债务? 你如何照顾你的开发人员的经验(DX)?
那么,你们是如何处理科技债务的呢? 如果你的Android应用在2023年使用Java, 你的公司可能在推动新功能,而不是处理技术债务. 这是可以理解的. 市场竞争激烈,需要快速的应用更新周期. 但技术债务有一个隐藏的影响:每次更新都会导致成本增加,因为工程师必须处理不稳定的代码,而这些代码很难重构. 公司很容易进入一个永无止境的循环 技术债务和成本. 或许值得暂停一下,投资于长期解决方案, 即使这意味着大规模的代码重构或更新你的代码库以使用像Kotlin这样的现代语言.
你如何通过DX照顾你的开发人员? 开发人员在其职业生涯的各个层面都需要支持:
高级开发人员对DX的关注尤其重要,因为他们的专业知识会影响到所有工程师. 高级开发人员喜欢学习和试验最新的技术. 跟上最新的趋势和语言版本将使您的团队成员发挥最大的潜力. 无论团队选择何种语言,这一点都很重要, 尽管不同的语言有不同的时间表:对于像Kotlin这样的年轻语言, an engineer working on legacy code can fall behind trends in less than one year; with mature languages like Java, 会花更长的时间.
而Java有广泛的应用, 不可否认,Kotlin已经抢了它的风头,成为开发新Android应用程序的首选语言. 谷歌把所有的精力都放在Kotlin上,它的新技术是Kotlin优先的. 现有应用程序的开发人员可以考虑将Kotlin集成到任何新代码中——intellij附带了一个自动的 Java转Kotlin工具并且应该研究超出我们最初的语言选择问题的因素.
Toptal工程博客的编辑团队向 Thomas Wuillemin 查看本文中提供的代码示例和其他技术内容.
是的,您可以从Kotlin调用Java代码,也可以从Java调用Kotlin代码.
Java和Kotlin是两种独立的语言. 尽管它们有某些相似之处,例如它们的典型用例(例如.g.(Android开发),它们有不同的功能和语法.
Kotlin是谷歌首选的Android开发语言,但许多Android应用程序仍然使用Java. 新的Android应用当然应该使用Kotlin, 但对于使用Java的现有Android应用程序来说,选择变得更加复杂.
在新的Android应用程序中使用Kotlin而不是Java是有意义的,因为谷歌的最新技术是Kotlin优先的, Kotlin有许多吸引人的特点, a large community, 以及大量的文档.
Kotlin和Java都是相对初学者友好的,有强大的社区和文档. In particular, Kotlin简洁的语法和特性的好处, 例如非空性, 使其比Java更容易学习.
Located in Zagreb, Croatia
Member since November 10, 2016
Gabriel是一名高级Android工程师,拥有8年用Kotlin和Java从头开始构建应用程序的经验, 并促进两种语言之间的转换. 加布里埃尔曾开发过价值数百万美元的应用程序,并在HBO和雅虎等公司拥有行业经验.
9
世界级的文章,每周发一次.
世界级的文章,每周发一次.
Join the Toptal® community.