Java 变得越来越像 Rust?

随着编程技术的增强和复杂性的提升,许多编程语言也纷纷效仿,Java 也不例外。

另一边,尽管社区内部问题重重,但 Rust 仍逐年获得开发人员的喜爱。这背后都是有原因的:Rust 的编译器让开发人员避免了各种问题。编译器对正确性的要求让一些开发人员开始感到不安全。

我想展示两个 Rust 特性,它们是 Rust 优秀之处的一部分,然后将它们与 Java 的最新创新进行比较。

免责声明:我绝不是说这些 Rust 特性导致 Java 中出现了相应的特性。如果是 Kotlin 或 Scala 在实现这些特性方面发挥了更大的作用,我也不会感到惊讶。但是,我很高兴看到 Rust 的特性也能在(某种程度上)Java 中找到!

Immutable Data

在编程领域,Immutable Data 是指一种一旦创建就不能更改的数据结构。在 Rust 中,数据默认是不可变的。

struct User {
// struct members are immutable
name: &'static str,
age: i32
}

fn main() {
// user and members are immutable
let user = User { name: "Bob", age: 42 };
}

如果我们希望数据是可变的,就必须显式声明它是可变的。

fn main() {
let mut user = User { name: "Bob", age: 42 };
user.name = "Jim";
}

现在,普通的 Java 对象(又称 POJO)在编写时通常默认具有可变性,而且相当冗长。

下面是它在 Java 8 中的样子:

public class User {
private String name;
private int age;

public User(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return this.name;
}

public int getAge() {
return this.age;
}

public void setName(String name) {
this.name = name;
}

public void setAge(int age) {
this.age = age;
}

public static void main(String[] args) {
User user = new User("Bob", 42);
user.setName("Jim");
System.out.println(user.getName());
}

// not to mention equals(), toString() and friends!
}

不过,多亏了现代 Java,记录类简化了这一过程,并考虑到了不变性,我们的代码也就不那么冗长了。下面是启用了预览功能的有效 Java 21 代码。

record User(String name, int age) {}

void main() {
final var user = new User("Bob", 42);
}

代数数据类型

在这段视频中,我们将看到 Rust 如何利用代数类型来帮助使无效状态无法表示,并有力地保证不会出现错误行为。

,时长11:24

在 Rust 中,这可以通过使用枚举来实现:

enum RealCat {
Alive { is_hungry: bool },
Dead
}

fn main() {
let real_cat: RealCat = RealCat::Alive { is_hungry: true };
match real_cat {
RealCat::Alive { is_hungry } => {
if is_hungry {
println!("The cat demands a sacrifice.");
} else {
println!("The cat is bored.");
}
},
RealCat::Dead => println!("Oh no!!!")
}
}

直到最近,Java 仍无法优雅地实现这一点。不过,从 Java 21 及以后的版本开始,您可以使用包含记录的密封接口和详尽的开关语法在 Java 中优雅地实现这一功能:

RealCat.java

public sealed interface RealCat permits RealCat.Alive, RealCat.Dead {

record Alive(boolean isHungry) implements RealCat {}
record Dead() implements RealCat {}

static void check(RealCat realCat) {
switch (realCat) {
case Alive aliveCat -> {
if (aliveCat.isHungry()) {
System.out.println("The cat demands a sacrifice.");
} else {
System.out.println("The cat is bored.");
}
}
case Dead _ -> System.out.println("Oh no!!!");
}
}
}

RealCatApplication.java

void main() {
final var hungryCat = new RealCat.Alive(true);
RealCat.check(hungryCat);
}

结论

有无数理由表明 Java 永远不会成为 Rust,但我很高兴看到 Rust 的一些强大功能正在进入 Java。这将巩固 Java 作为商业世界首选编程语言之一的长期地位。由于 OpenJDK 项目致力于提高开发人员的工作效率,Java 在过去 28 年中一直占据着重要的市场份额,即使不能在未来 28 年中重新夺回重要的市场份额,也有望保持这一地位。

相关推荐
yinhezhanshen几秒前
理解rust里面的copy和clone
开发语言·后端·rust
forestsea5 分钟前
使用 Spring Boot 和 GraalVM 的原生镜像
java·spring boot·spring native·原生映像
逸狼7 分钟前
【JavaEE进阶】Spring AOP入门
java·java-ee
色空大师11 分钟前
【idea】实用插件
java·ide·intellij-idea
Jtti16 分钟前
PHP在Debian环境上的并发处理能力如何
开发语言·debian·php
栗筝i18 分钟前
Spring 核心技术解析【纯干货版】- XIX:Spring 日志模块 Spring-Jcl 模块精讲
java·后端·spring
时光追逐者20 分钟前
在 Blazor 中使用 Chart.js 快速创建数据可视化图表
开发语言·javascript·信息可视化·c#·.net·blazor
独好紫罗兰23 分钟前
洛谷题单3-P5718 【深基4.例2】找最小值-python-流程图重构
开发语言·python·算法
小天努力学java25 分钟前
【面试题】如何用两个线程轮流输出0-200的值
java·开发语言
云边有个稻草人28 分钟前
【C++】第八节—string类(上)——详解+代码示例
开发语言·c++·迭代器·string类·语法糖auto和范围for·string类的常用接口·operator[]