Java 变得越来越像 Rust

Java 变得越来越像 Rust

介绍

随着编程的增强和复杂性越来越流行,许多编程语言也相互效仿。 Java 也不例外。

尽管社区内部存在问题,Rust 仍逐年赢得了开发人员的喜爱。并且有充分的理由:由于编译器,Rust 使开发人员能够避免整个类别的问题。编译器要求正确性,以至于一些开发人员开始遇到一些不安全感。

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

免责声明:我绝不声称这些 Rust 功能导致其对应功能出现在 Java 中。如果 Kotlin 和或 Scala 在实现这一点方面更具影响力,我不会感到惊讶。但我很高兴看到 Rust 功能也可以(在某种程度上)在 Java 中找到!

不可变数据(Immutable Data)

在 Rust 中,数据默认是不可变的。

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 };
}  

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

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

现在,一个普通的 Java 对象(又名 POJO)通常是默认可变,而且相当冗长。 Java 8 中的代码如下:

java 复制代码
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,record 类在考虑到不变性的情况下简化了这一点,并且我们的代码远没有那么冗长。以下是启用了预览的有效 Java 21 代码。

java 复制代码
record User(String name, int age) {}  

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

代数数据类型(Algebraic Data Types)

在这段 YouTube 视频中,我们看到 Rust 如何利用代数类型来帮助使无效状态变得不可表示,并强有力地保证防止错误行为。在 Rust 中,这是使用枚举完成的:

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 及更高版本开始,您可以使用包含记录的密封接口并使用详尽的 switch 语法在 Java 中优雅地实现此功能:

RealCat.java

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

java 复制代码
void main() {
    final var hungryCat = new RealCat.Alive(true);
    RealCat.check(hungryCat);
}

结论

有无数(充分)的理由表明 Java 永远不会成为 Rust,但我很高兴看到 Rust 的一些强大功能进入了 Java。这将巩固 Java 作为商业世界首选编程语言之一的长期地位。 Java 在过去 28 年中一直拥有重要的市场份额,并且由于 OpenJDK 项目致力于提高开发人员的生产力,因此在未来 28 年中即使不能重新获得重要的市场份额,也有望保持这一市场份额。

相关推荐
SL_staff8 分钟前
破除执行黑箱:用目标地图、资源热力图与健康度看板构建可下钻的执行事实链
java·开源·全栈
骑着蜗牛撵大象32722 分钟前
让 Codex 值夜班:把告警排查与巡检接成可回滚的自动化链路
android·java·运维·ai·自动化·codex·智能体
木头科技25 分钟前
【AI 工程化第十八篇】Spring AI 语音 Agent 实战:实时转写、WebSocket、流式 TTS 与打断机制
java·人工智能·安全·spring·性能优化
cfm_291431 分钟前
SpringPrototype作用域
java
铁皮饭盒40 分钟前
这6个小模型各有绝活, 且都可cpu/浏览器端运行
前端·后端
大风起兮云飞扬丶1 小时前
Java——枚举
java·开发语言
小灰灰搞电子1 小时前
Rust+Slint 实现高级动态消息提示框源码分享
开发语言·rust
qq_406981031 小时前
大白话rust系列08 当变量遮蔽遇上引用,探究变量遮蔽的本质
开发语言·后端·rust
ReStock活库1 小时前
Zephyr异步SPI调用返回后,为什么不能立即复用发送缓冲区?
java·前端·网络
微微%2 小时前
从零搭建一个java开发环境
java·idea2023·jdk17