你好,世界
Kotlin是一种静态类型语言,在JVM上运行,并且与现有Java代码具有100%的互操作性。对于大多数Java开发人员来说,下面的程序应该非常熟悉:
包 com。bugsnag。科特林 ;
公共 课 App {
public static void main(String [] args){
系统。出。println(“Hello World!”);
}
}
以下将在Kotlin中打印“Hello World” :
fun main(args:Array < String >){
println(“Hello World!”)
}
一些差异是显而易见的,例如缺少分号以及我们的代码是多么简洁。
科特林与 Java的
为了了解Kotlin,让我们仔细看看它的功能以及它们与Java的比较。
无安全性
我们将首先探索Kotlin最有用的功能之一 - 它支持null安全性。在Java中,任何对象都可以null
。这意味着必须在整个代码库中添加运行时检查以防止NullPointerException
崩溃,这通常被语言设计者称为十亿美元的错误。
静态 类 用户 {
字符串 名称 ;
}
public void printUsername(User user){
如果(用户。名字 != 空){
FOO(用户。名。长度());
}
}
在Kotlin中,对象的引用必须是可空的或非空的:
class User(var name:String ?)// name属性可以为null
class User(var name:String)// name属性不能为null
如果开发人员试图将可以为空的对象传递给第二个类,则会发生编译时错误。
安全呼叫运营商
以下对大多数Java开发人员来说非常熟悉。所述user
参数可以是null
,所以需要运行时检查以确保NPE
避免。
void printUsername(User user){
如果(用户。的getName()!= 空){
FOO(用户。的getName()长度());
} else {
foo(null); //提供一个null整数
}
}
void foo(整数 长度){}
Kotlin可以通过Safe Call
操作员简化这一过程 。如果name
不为null,则其长度将作为参数传递。否则,将传递空引用。
fun printUsername(user:User){
FOO(用户。名字?。长度)如果user.name为空//返回null
}
fun foo(length:Int ?){}
或者,如果在值为null时执行代码没有意义,我们可以使用let
:
fun foo(nullableUser:User ?){
nullableUser ?。let { printUsername(nullableUser)} //只打印非空用户名
}
fun printUsername(user:User){} // User是非空引用
类定义
与Java相比,Kotlin 类非常简洁。下面的类定义了三个字段,getter和setter超过30行!
class User {
最终 字符串 名称 ;
int age = 18 ;
字符串 地址 ;
public User(String name,int age,String address){
这个。name = name ;
这个。年龄 = 年龄 ;
这个。地址 = 地址 ;
}
public String getName(){
返回 名称 ;
}
public int getAge(){
回归 年龄 ;
}
public void setAge(int age){
这个。年龄 = 年龄 ;
}
public String getAddress(){
返回 地址 ;
}
public void setAddress(String address){
这个。地址 = 地址 ;
}
}
在Kotlin中,我们可以使用一行代码实现相同的功能。
class User(val name:String,var age:Int = 18,var address:String ?)
不可变引用也更容易。这只是从var
关键字切换到的问题val
。
您可能已经注意到,对于Kotlin,可以为参数提供默认值。这意味着可以在Kotlin中消除Java模式,例如Builder模式 。这也可以大大减少语法糖所需的代码量,例如公共API中的方法链。
数据类
如果我们类的主要目的是保存数据,例如来自API的JSON有效负载,事情会变得更加简洁。在Kotlin中,这些被称为数据类。
data class User(val name:String,var age:Int = 18,var address:String ?)
只需添加data
关键字会自动生成equals()
,hashCode()
,toString()
,并copy()
为我们的类实现。省略了此类的等效Java实现,以节省读者的理智和带宽成本。
类型推断
Kotlin使用类型推断,这进一步增加了它的简洁性。考虑一下这个Java类:
class AbstractSingletonProxyFactoryBean {}
public void foo(){
AbstractSingletonProxyFactoryBean bean = new AbstractSingletonProxyFactoryBean();
}
而Kotlin中的等价物看起来像这样:
class AbstractSingletonProxyFactoryBean
fun foo(){
val bean = AbstractSingletonProxyFactoryBean()//自动推断类型
}
功能
类型推断渗透到整个语言中。在需要时可以是显式的或隐式的,如下面定义相同函数的两种方法所示:
int add(int a,int b){
返回 a + b ;
}
fun add(a:Int,b:Int):Int { //显式返回类型
返回 a + b
}
fun add(a:Int,b:Int)= a + b //推断的返回类型
属性
Kotlin Properties简直太棒了。考虑以下Java类,它使用访问器方法定义单个字段:
class Book {
字符串 作者 ;
String getAuthor(){
回归 作者 ;
}
void setAuthor(String author){
这个。作者 = 作者 ;
}
}
书 书 = 新的 图书();
书。setAuthor(“Kurt Vonnegut”);
系统。出。的println(书。getAuthor());
通过定义声明author
属性的类,可以在Kotlin的四行中实现等效功能。我们将自动生成我们的getter和setter:
class Book(var author:String ?)
val book = 书()
书。author = “Kurt Vonnegut”
println(书。作者)
自定义访问者
如果getter和setter需要自定义行为,则可以覆盖默认行为。例如:
class Person(var firstName:String,var lastName:String){
var fullName:String
get()= “$ {firstName} $ {lastName}”
set(value){
val split = value。拆分(“”)
firstName = split [ 0 ]
lastName = split [ 1 ]
}
}
如果我们需要验证字段或将其限制为某些输入,也可以使用支持字段:
set(value){
如果(“圣诞老人”。等于(值))字段 = “蚝HO”
}
互通性
Kotlin的另一个优点是可以从同一个项目中的Java代码中调用它,反之亦然。
公共 类 MyJavaClass {
public String authorName ;
public boolean isTruthyValue(){
返回 true ;
}
}
以下Kotlin函数实例化一个新的Java对象,并使用常规的Kotlin语法访问其方法和字段。如果您想通过向现有Java代码库添加少量Kotlin来将脚趾浸入水中,这将非常方便。
fun main(args:Array < String >){
val obj = MyJavaClass()
的println(OBJ。AUTHORNAME)
的println(OBJ。isTruthyValue)
}
还值得一提的是,Kotlin可以反编译回Java,因此如果您的团队不喜欢该语言或遇到技术障碍,那么完全可以迁移回来。
实用方法
所有Java开发人员都会非常熟悉实用程序或帮助程序类。静态方法将执行Java标准库中不可用的一些有用操作,并将在代码库中调用:
class StringUtils {
static String sortStringChars(String input){
char [] chars = 输入。toCharArray();
数组。排序(字符);
return new String(chars);
}
}
StringUtils。sortStringChars(“azbso”); //返回“abosz”
在Kotlin中,扩展允许将其他功能添加到现有类中,而无需扩展或包装该类。例如,以下内容将向该类添加一个sortStringChars
函数String
:
有趣的 字串。sortStringChars():String {
val chars = 这个。toCharArray()
数组。排序(字符)
return String(chars)
}
fun main(args:Array < String >){
“azbso”。sortStringChars()//返回“abosz”
}
这导致语法更易读 - 但要注意。强大的力量带来了巨大的责任。
功能编程
Kotlin完全支持lambda表达式。有限的Java 8支持刚刚添加到Android中,这使得Kotlin的功能编程功能特别受欢迎。
//为名称以“J”开头的所有作者筛选一个列表
val input = listOf(“JK罗琳”,“查尔斯达尔文”)
val authors = 输入。过滤器 { 作者 - > 作者。startsWith(“J”)}
println(作者)// JK罗琳
也可以在Collections上使用诸如filter
和map
直接构造,这在大多数Android设备上目前都不支持。
fun main(args:Array < String >){
val input = listOf(“JK罗琳”,“查尔斯达尔文”,“”)
val authors = 输入。过滤 { !它。isEmpty()} //删除空值
。map { Author(it)} //将字符串映射到作者对象
。sortedBy { it。name } //按作者名排序
println(authors)//按字母顺序打印作者
}
Reactive Streams最近在Android世界中流行起来,RxKotlin库也为Kotlin提供了支持。
val cereals = listOf(“Kellogs Coroutines”,“Cocoa Pods”,“Locky Charms”)
谷物。toObservable()
//在后台线程上执行一些密集/复杂的计算
。subscribeBy(onNext = {
println(it)//观察主线上的每个谷物并打印出来
})
Kotlin Native和Javascript
Kotlin主要针对JVM,但也可以 使用LLVM工具链转换为Javascript或编译为本机代码。这两个目标在开发阶段还处于初期阶段,但对于希望在整个堆栈中使用一种语言进行编程的人来说,这显示了很大的希望。
Kotlin Native特别有趣,因为Swift 看起来与Kotlin非常相似,这意味着有朝一日可能会在Android和iOS应用程序中使用相同的本机代码库。
另一个值得一提的是Gradle Script Kotlin,它将静态类型的所有好处带到现有的Gradle DSL和Spring Boot,后者为Kotlin提供官方支持1.5
。
潜在的下行
那么Kotlin的缺点是什么?
在Android上,应用程序大小是一个潜在的问题。Kotlin目前为您的应用程序大小增加了大约1Mb, 并使用了大约7,000种方法,尽管其中大部分都可以被Proguard剥离。对于传统的Java桌面应用程序来说,这不是什么大不了的事,但对于拥有更多资源限制的移动设备,这对某些团队来说可能是一个交易破坏者。
Kotlin并没有和Java一样长,因此,识别不良做法和代码味道要困难得多。Java有22年的良好实践和linting工具可供借鉴,而Kotlin却没有。例如,扩展函数是一个非常强大的功能,但可以轻松地用于应该使用类和抽象的地方。
更人性化的因素是尽管Kotlin与Java非常相似; 学习一门新语言总会有一段时间,这会导致生产力暂时下降。
特别是如果团队中的每个人都在过去十年中成为Java专家,他们可能不愿意放弃并以他们不熟悉的语言重新开始。外部客户可能对Kotlin感到不太满意,因为有人认为它与Java一样久不存在,并且更为未知。
为什么Kotlin击败Java
让我们总结一下Kotlin的一些主要优点:
科特林是远远比Java更简洁
Lambdas和功能构造已经开箱即用多年
100%与现有Java代码的互操作性
Kotlin实际上消除了最常见的Java错误之一,可怕的
NullPointerException
IntelliJ IDEA提供出色的工具支持
这种语言是从头开始编写的,因此,它 感觉就像是每天都在其中编程的人设计的语言
我们认为,由于这些原因,Kotlin在Android上击败了Java。在传统的Java桌面应用程序中,由于Java 8包含可比较的语言功能,例如lambda,流和其他,因此它是一个更接近的竞争。但是,我们仍然相信Kotlin的简洁性在这种情况下获胜。
关于Kotlin入门的建议
在一篇博客文章中总结一下编程语言是不可能的,所以如果你或你的团队有兴趣使用Kotlin,我们的建议只是试一试!
最常见的两条路线是在Kotlin中编写单元测试或将现有的Utils类转换为Kotlin。IntelliJ IDEA还提供了一个方便的自动转换快捷方式,可将现有Java代码迁移到Kotlin。虽然这不一定会给你最惯用的Kotlin,但它是一种在你熟悉的代码库中学习语法的好方法。
最重要的是不断评估每个人是否对Kotlin的采用水平感到满意,并确定任何痛点或隐藏的陷阱。
Kotlin是Java的一个非常好的替代品,如果做得好,它有可能提高开发人员的快乐,降低代码库的复杂性,并提高业务的生产力。