1. 概述

Java 21 已经到来,其中的新特性表明Java正逐渐变得更加适合初学者使用,特别是通过未命名类和实例主方法【1】。这些新功能对于降低Java编程语言的学习门槛至关重要。

在这个教程中,我们将探讨这些新特性,理解它们如何使学习曲线对初学者更加平滑。

2. 编写基本Java程序

传统上,对于初学者来说,编写他们的第一个Java程序比其他编程语言稍微复杂一些。一个基本的Java程序需要声明一个public类,其中包含一个public static void main(String[] args)方法,作为程序的入口点。

所有这些都是为了在控制台打印出一个简单的"Hello world":

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

Java 21极大地简化了编写简单程序的方式:

void main() {
    System.out.println("Hello, World!");
}

我们将详细介绍如何利用新特性实现这种语法简化。

3. 实例主方法

实例main()方法的引入使得开发者能够采用更动态的方式来初始化应用程序。

3.1. 理解实例主方法

这改变了Java程序声明入口点的方式。实际上,Java早期要求在public类中有一个带有String[]参数的static main()方法,如前一节所述。

这个新的规范更为宽容。它允许main()方法具有不同的访问级别:publicprotected或默认(包内)。

而且,方法不再需要是static,也不再需要String[]参数:

class HelloWorld {
    void main() {
        System.out.println("Hello, World!");
    }
}

3.2. 选择启动协议

改进后的启动协议会自动为我们的程序选择一个起点,考虑可用性和访问级别。

实例main()方法应始终具有非private的访问级别。此外,启动协议遵循特定顺序来决定使用哪个方法:

  1. 在启动类中声明的static void main(String[] args)方法
  2. 在启动类中声明的static void main()方法
  3. 在启动类或超类中声明的void main(String[] args)实例方法
  4. void main()实例方法

当一个类声明了一个实例main()方法,并继承了一个标准的static main()方法【2】时,系统将调用实例main()方法。在这种情况下,JVM会在运行时发出警告。

例如,假设我们有一个名为HelloWorldSuper的超类,它实现了一个久经考验的main()方法:

public class HelloWorldSuper {
    public static void main(String[] args) {
        System.out.println("Hello from the superclass");
    }
}

这个超类被HelloWorldChild类扩展:

public class HelloWorldChild extends HelloWorldSuper {
    void main() {
        System.out.println("Hello, World!");
    }
}

使用--source 21--enable-preview标志编译超类并运行子类:

javac --source 21 --enable-preview HelloWorldSuper.java
java --source 21 --enable-preview HelloWorldChild

在控制台上,我们会看到以下输出:

WARNING: "void HelloWorldChild.main()" chosen over "public static void HelloWorldSuper.main(java.lang.String[])"
Hello, World!

我们可以看到JVM如何警告我们程序中有两个可能的入口点。

4. 未命名类

未命名类是为简化初学者的学习曲线而设计的一个重要特性。它允许方法、字段和类存在,而无需显式声明类。

通常情况下,Java中的每个类都存在于一个包内,每个包又在一个模块中。然而,未命名类存在于未命名包和未命名模块中。它们是final的,只能扩展Object类,而不实现任何接口。

考虑到这些,我们可以在代码中不显式声明类的情况下声明main()方法:

void main() { 
    System.out.println("Hello, World!");
}

利用这两个新特性,我们成功地将程序简化为一个对初学者来说更容易理解的版本。

未命名类几乎与显式声明的类完全相同。其他方法或变量被视为未命名类的成员,因此我们可以将它们添加到类中:

private String getMessage() {
    return "Hello, World!";
}
void main() {
    System.out.println(getMessage());
}

尽管它们简单且灵活,但未命名类有其固有的限制。

直接构造或按名称引用是不可能的,它们不定义可以从其他类访问的任何API。这种不可访问性也导致[Javadoc]【3】工具在生成此类的API文档时出现问题。不过,未来Java版本可能会调整和增强这些行为。

5. 总结

在这篇文章中,我们了解到Java 21通过引入未命名类和实例主方法,在提升用户体验方面取得了重大进展,尤其是对于编程旅程的初学者。

通过简化编程结构的方面,这些特性让新手能够更快地专注于逻辑思维和解决问题。

如常,源代码可在GitHub上找到【4】。