10 reasons to switch from Java to Kotlin right now! 1. Null safety 2. Highlighting the main constructor 3. Initialization and logic of working with DTO classes 4. Explicit declaration of mutable and immutable fields - var/val 5. Collections are immutable by default 6. Extensions. 7. Working with complex classes using primitive methods 8. Possibility of one-line methods really on one line 9. Scope functions 10. Easy to integrate into an existing Java project. Conclusions

2025-06-10

立即从 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
}
Enter fullscreen mode Exit fullscreen mode

2. 突出显示主要构造函数

底线是:有一个主构造函数和一个次构造函数。辅助函数需要将主构造函数作为父类的构造函数来调用。

class Cat(val name: String, val color: String, val height: Int) {

    constructor(name: String) : this(
        name = name,
        color = "fixed color",
        height = 10
    )
}
Enter fullscreen mode Exit fullscreen mode

3. DTO 类的初始化和逻辑

这个例子虽然陈旧,但却尽可能清晰。

data class Cat(val name: String, val color: String, val height: Int)
Enter fullscreen mode Exit fullscreen mode

现在在 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);
    }
}
Enter fullscreen mode Exit fullscreen mode

在我看来,这里甚至评论都是多余的。

Kotlin 中的数据类指针默认隐含了所有字段的 getter、setter(针对 var 字段)、equals、hashcode 和 toString 方法。如果需要,你可以以自己的方式重写这些方法,但这很少需要。

class Cat(val name: String, val color: String, val height: Int) {

    override fun toString(): String = "overridden toString"
}
Enter fullscreen mode Exit fullscreen mode

4. 可变和不可变字段的显式声明 - var/val

另一个优点:在 Kotlin 中,你可以获得非常简单优雅的构造。如果你希望 dto 字段可更改,则可以使用 var 来声明它。这样就会创建 setter 方法,并且该字段不会是 final 的。

如果需要使字段不可变,则应该使用 val 进行声明。这样看起来非常简洁美观。而且无需后续使用辅助方法。

例如:颜色和高度字段可以在创建后更改,而名称只能在对象初始化时更改:

data class Cat(val name: String, var color: String, var height: Int)
Enter fullscreen mode Exit fullscreen mode

5. 集合默认是不可变的

稍后在 Java 中出现的功能早已在 Kotlin 中出现 - 创建的集合立即变为不可变的。

val list = listOf("one", "two")
val map = mapOf(1 to "one", 2 to "two")
val set = setOf(1, 2 ,3)
Enter fullscreen mode Exit fullscreen mode

对这些集合的任何更改都会在转换后创建一个新的不可变集合:

val list = listOf("one", "two")
val list2 = list.plus("three")
Enter fullscreen mode Exit fullscreen mode

但是你不能单独更改任何元素。对于经典的可变集合,使用显式可变的类似物:

val list = mutableListOf("one", "two")
val map = mutableMapOf(1 to "one", 2 to "two")
val set = mutableSetOf(1, 2 ,3)
Enter fullscreen mode Exit fullscreen mode

6.扩展。

比如,你在其他 API 中有一个非常不方便的模型,它以非常高的嵌套层级存储数据。在 Java 中,你需要编写一个转换器,将一个无用的模型转换为一个有用的模型。

在 Kotlin 中,您可以为任何类添加扩展,甚至可以为来自外部库的类添加扩展,并根据需要使用它:

data class SomeBadModel(
    val innerModel: EvenBadModel
)
data class EvenBadModel(tons of fields)


fun SomeBadModel.doGoodStuff(val any: Any?): Any? = usefullLogicHere
Enter fullscreen mode Exit fullscreen mode

7. 使用原始方法处理复杂类

Kotlin 的一个优点,也是我一直乐在其中的一点,就是它能够使用运算符对复杂类进行基本运算。如果需要对 BigDecimal 进行加法运算,只需将其转换为加法即可。无需在第一个项上显式调用该方法。

val a = BigDecimal(1)
val b = BigDecimal(2)
val sum = a + b
Enter fullscreen mode Exit fullscreen mode

在Java中,需要调用一个特殊的方法:

BigDecimal a = new BigDecimal(1);
BigDecimal b = new BigDecimal(2);
BigDecimal sum = a.add(b);
Enter fullscreen mode Exit fullscreen mode

数组也一样:如果要从可变数组中删除一个元素,只需写出数组减去该元素即可。如果该元素存在,则会被删除。

val list = listOf("one", "two") - "one" // list = ["two"]
Enter fullscreen mode Exit fullscreen mode

8. 单行方法的可能性

如果方法很简单,只包含一个操作或一行代码就能写出的一系列操作,那么就不需要写花括号和 return 了。直接写:

fun getReviewByTitle(title: String): List<Review> = reviewRepository.getAllByTitle(title)
Enter fullscreen mode Exit fullscreen mode

而不是 Java 选项:

public List<Review>(String title) {
        return reviewRepository.getAllByTitle(title);
    }
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

或者初始化对象并另外初始化其 var 字段:

class Cat(val name: String, val height: Int) {
    var color: String? = null
}

fun bar() = Cat("Fred",10).apply { color = daoService.getPopularColor() }
Enter fullscreen mode Exit fullscreen mode

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
PREV
一劳永逸:JavaScript 中的 const 不是不可变的
NEXT
分布式系统中的时钟