立即从 Java 切换到 Kotlin 的 10 个理由!
1. 空安全
2. 突出显示主要构造函数
3. DTO 类的初始化和逻辑
4. 可变和不可变字段的显式声明 - var/val
5. 集合默认是不可变的
6.扩展。
7. 使用原始方法处理复杂类
8. 单行方法的可能性
9. 作用域函数
10.易于集成到现有的Java项目中。
结论
我叫 Viacheslav Aksenov,是一名大型复杂后端系统的开发人员。我最初使用 Java 7 进行开发,后来升级到 Java 8,有时甚至会用到 Java 11。去年,我用 Kotlin 编写了所有新代码,这彻底改变了我的生活。我之前并不知道 Kotlin 可以用于后端开发,甚至更多——可以使用 Spring、Jackson 等所有顶级 Java 框架进行后端开发。
所以我想与你们分享我的快乐,并给出 10 个理由说明为什么你们应该关注 Kotlin 并将其集成到你们的项目中。
1. 空安全
在 Kotlin 中,需要明确指出某个方法是否可以返回 null。因此,我们可以假设所有数据都已经封装在 Optional 的类似物中。这样,NullPointerException 就很少发生,你几乎不会察觉。
fun saveReviewNullable(r: Review): Review? = reviewRepository.save(r)
fun bar(r: Review) {
val savedReviewNullable: Review = saveReviewNullable(r)!! // can throw NPE. Not safety
val savedReviewNotNull: Review = saveReviewNullable(r) ?: Review() // safety way
}
2. 突出显示主要构造函数
底线是:有一个主构造函数和一个次构造函数。辅助函数需要将主构造函数作为父类的构造函数来调用。
class Cat(val name: String, val color: String, val height: Int) {
constructor(name: String) : this(
name = name,
color = "fixed color",
height = 10
)
}
3. DTO 类的初始化和逻辑
这个例子虽然陈旧,但却尽可能清晰。
data class Cat(val name: String, val color: String, val height: Int)
现在在 Java 中也一样:
public class Cat {
private final String name;
private final String color;
private final Integer height;
public Cat(String name, String color, Integer height) {
this.name = name;
this.color = color;
this.height = height;
}
public String getName() {
return name;
}
public String getColor() {
return color;
}
public Integer getHeight() {
return height;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cat cat = (Cat) o;
return Objects.equals(name, cat.name) && Objects.equals(color, cat.color) && Objects.equals(height, cat.height);
}
@Override
public int hashCode() {
return Objects.hash(name, color, height);
}
}
在我看来,这里甚至评论都是多余的。
Kotlin 中的数据类指针默认隐含了所有字段的 getter、setter(针对 var 字段)、equals、hashcode 和 toString 方法。如果需要,你可以以自己的方式重写这些方法,但这很少需要。
class Cat(val name: String, val color: String, val height: Int) {
override fun toString(): String = "overridden toString"
}
4. 可变和不可变字段的显式声明 - var/val
另一个优点:在 Kotlin 中,你可以获得非常简单优雅的构造。如果你希望 dto 字段可更改,则可以使用 var 来声明它。这样就会创建 setter 方法,并且该字段不会是 final 的。
如果需要使字段不可变,则应该使用 val 进行声明。这样看起来非常简洁美观。而且无需后续使用辅助方法。
例如:颜色和高度字段可以在创建后更改,而名称只能在对象初始化时更改:
data class Cat(val name: String, var color: String, var height: Int)
5. 集合默认是不可变的
稍后在 Java 中出现的功能早已在 Kotlin 中出现 - 创建的集合立即变为不可变的。
val list = listOf("one", "two")
val map = mapOf(1 to "one", 2 to "two")
val set = setOf(1, 2 ,3)
对这些集合的任何更改都会在转换后创建一个新的不可变集合:
val list = listOf("one", "two")
val list2 = list.plus("three")
但是你不能单独更改任何元素。对于经典的可变集合,使用显式可变的类似物:
val list = mutableListOf("one", "two")
val map = mutableMapOf(1 to "one", 2 to "two")
val set = mutableSetOf(1, 2 ,3)
6.扩展。
比如,你在其他 API 中有一个非常不方便的模型,它以非常高的嵌套层级存储数据。在 Java 中,你需要编写一个转换器,将一个无用的模型转换为一个有用的模型。
在 Kotlin 中,您可以为任何类添加扩展,甚至可以为来自外部库的类添加扩展,并根据需要使用它:
data class SomeBadModel(
val innerModel: EvenBadModel
)
data class EvenBadModel(tons of fields)
fun SomeBadModel.doGoodStuff(val any: Any?): Any? = usefullLogicHere
7. 使用原始方法处理复杂类
Kotlin 的一个优点,也是我一直乐在其中的一点,就是它能够使用运算符对复杂类进行基本运算。如果需要对 BigDecimal 进行加法运算,只需将其转换为加法即可。无需在第一个项上显式调用该方法。
val a = BigDecimal(1)
val b = BigDecimal(2)
val sum = a + b
在Java中,需要调用一个特殊的方法:
BigDecimal a = new BigDecimal(1);
BigDecimal b = new BigDecimal(2);
BigDecimal sum = a.add(b);
数组也一样:如果要从可变数组中删除一个元素,只需写出数组减去该元素即可。如果该元素存在,则会被删除。
val list = listOf("one", "two") - "one" // list = ["two"]
8. 单行方法的可能性
如果方法很简单,只包含一个操作或一行代码就能写出的一系列操作,那么就不需要写花括号和 return 了。直接写:
fun getReviewByTitle(title: String): List<Review> = reviewRepository.getAllByTitle(title)
而不是 Java 选项:
public List<Review>(String title) {
return reviewRepository.getAllByTitle(title);
}
9. 作用域函数
本着强调上下文的精神,朝着函数式编程迈出了有趣的一步:lambda 可以随意旋转。
函数有 let、apply、also、with、run 等。由于它们种类繁多,一开始你可能会想:哪种函数适合特定情况?但当你习惯了之后,你就会明白以前没有它们的时候是怎么生活的。
一个简单的例子:获取结果并以某种方式处理它:
fun save(review: Review): Review = repository.save(review)
fun bar(r: Review) = saveReview(r).let { it.comment + it.date}
或者初始化对象并另外初始化其 var 字段:
class Cat(val name: String, val height: Int) {
var color: String? = null
}
fun bar() = Cat("Fred",10).apply { color = daoService.getPopularColor() }
10.易于集成到现有的Java项目中。
如果您只是希望将 Kotlin 用于后端,请记住,在 Java 8 启动项目的环境中,您可以用 Kotlin 运行已编译的项目,而无需费力。是的,在同一个 JVM 上,在同一个环境中,只需付出最少的努力。
我发现,即使在同一个应用程序中,也可以同时使用 Java 和 Kotlin 的类。所有神奇的事情都发生在编译时。根据设置,您可以指定优先构建哪个类:Kotlin 类还是 Java 类。
现在可以将 Kotlin 源代码从 Java LTS - 8、11 和(迄今为止是实验性的)16 编译为字节码。
结论
有人可能会说,这就像糖糖一样,他们说得没错。但我个人认为:如果语言中包含大量样板代码,你无需时刻思考它们,开发过程就会变得更简单,错误也会更少。但你需要更频繁地思考代码风格,因为没有它,你可能会犯很多错误。
现在我仍然继续用 Java 编写和查看代码,但 99% 的情况下这是因为我作为导师参与的教育计划。
我建议每个人都尝试一下 - 至少在一个宠物项目上尝试一下,以了解 Kotlin 范式是否适合您。
鏂囩珷鏉ユ簮锛�https://dev.to/vaksenov/10-reasons-to-switch-from-java-to-kotlin-right-now-3ihj