Kotlin现在非常流行它在编译时提供null安全性代码更简洁。它比Java好你应该切换到Kotlin否则你只能静坐。然而在转向Kotlin之前请听听这个故事——在这个故事中那些奇怪的东西让我们无法忍受最后不得不用Java来重写整个项目。
我们尝试过Kotlin但现在我们使用Java 10来重写代码。
我有一组我最喜欢的JVM语言/main目录中的Java代码和/test目录中的Groovy代码是我最喜欢的组合。在2017年夏天我的团队开始了一个新的微服务项目和往常一样我们讨论了使用什么编程语言和技术。我们想尝试新的东西所以决定尝试Kotlin。由于我们在Kotlin中找不到替代Spock的测试框架我们决定继续在/test目录中使用Groovy(Spek不如Spock)。在2018年的冬天在使用Kotlin几个月之后我们总结了它的优点和缺点并得出结论Kotlin导致我们的生产力下降。因此我们开始使用Java重写这个微服务。
原因如下:
名称阴影
类型推断
编译时空安全性
班级文字
反向类型声明
伴随对象
集合文字
也许语法
数据类
公开课
陡峭的学习曲线
命名掩蔽
Kotlin的命名掩盖对我来说是最大的惊喜。例如以下功能:
Fun inc(num: Int){
Val num=2
如果(num> 0){
Val num=3
}
Println(“num:”+ num)
}
打电话给inc(1)时会打印什么?在Kotlin中方法参数按值传递因此我们无法修改num参数。此设计是正确的因为不应修改方法参数。但是我们可以定义另一个具有相同名称的变量并将其初始化为任何所需的值。现在在方法范围中有两个名为num的变量。当然您一次只能访问一个num变量。所以从根本上说num的值已经改变了。
我们还可以向if块添加另一个num(新代码块作用域)。
在Kotlin中在调用inc(1)时打印2而在Java中无法编译等效代码:
Void inc(int num){
Int num=2; //错误:变量'num'已在范围
中定义如果(num> 0){
Int num=3; //错误:变量'num'已在范围
中定义}
System.out.println(" num:" + num);
}
命名掩码不是Kotlin独有的它在编程语言中很常见。在Java中我们习惯使用方法参数来屏蔽类字段:
公共类Shadow {
Int val;
公共阴影(int val){
This.val=val;
}
}
Kotlin的命名掩盖有点矫枉过正这绝对是Kotlin团队的设计缺陷。 IDEA团队试图通过为每个着色变量显示警告(“名称阴影”)来解决此问题。两个团队属于同一家公司也许他们可以就影子问题达成共识?我认为IDEA团队是对的因为我无法想象掩蔽方法参数的有用性。
类型推断
在Kotlin中当使用var或val声明变量时通常会要求编译器根据右侧的表达式猜测变量类型。我们称之为局部变量类型推断这对程序员来说是一个很大的改进因此我们可以简化代码而不影响静态类型检查。
例如这行Kotlin代码:
Var a=“10”
将由Kotlin编译器翻译成:
Var a: String=" 10"
这就是Kotlin曾经比Java更好的地方。我故意说“曾经”那是因为Java 10现在也有局部变量类型推断。
Java 10中的类型推断:
Var a=“10”;
公平地说我需要补充的是Kotlin在这方面仍然有点好因为在Kotlin中类型推断可以用在其他环境中例如一行代码方法。
编译时间无效安全
null安全类型是Kotlin的杀手级功能。在Kotlin中默认情况下类型不可为空。如果您需要可以为空的类型则需要添加?例如:
Val a:字符串?=null //ok
Val b: String=null //编译错误
如果你使用一个没有空检查的可空变量你将无法编译例如:
Println(a.length) //编译错误
Println(a?length) //很好打印空
Println(a?length? 0) //很好打印0