为什么分号不是必需的,但允许在类定义的末尾使用?

2022-09-02 11:40:02

我正试图从C++转向Java。

我想知道的是,C++,在类定义之后,分号()是必需的,但在Java中则不是。;

也就是说,在C++:

class Person {
    public:
    string name;
    int number;
}; // Note this semicolon

但是在Java中:

class Person {
    public String name;
    public int number;
} // Semicolon is not required

没关系,我明白。

但是,我的问题是

当我在类定义末尾添加分号时,Java也可以工作,例如:

class Person {
    public String name;
    public int number;
}; // Now this semicolon is confusing me!

我已经编译并执行了为Java显示的两个程序片段,它们都可以工作。谁能解释为什么会这样?Java中类定义末尾的分号代表什么?

我很抱歉,如果这个问题的质量很低,但我真的需要澄清这一点。我希望Java专家能帮助我。

好吧,我已经在类定义和其他相关问题中看到了分号。

提前致谢。


答案 1

我已经编译并执行了为Java显示的两个程序片段,它们都可以工作。谁能解释为什么会这样?

这是允许的,因为Java语法说它是允许的;请参阅 JLS 7.6

Java中类定义末尾的分号代表什么?

无。它是可选的“句法噪声”。

JLS对此的解释如下:

在编译单元的类型声明级别出现额外的 “;” 标记对编译单元的含义没有影响。在 Java 编程语言中允许使用离散分号,只是为了让步于习惯于在类声明后放置 “;” 的C++程序员。它们不应该在新的 Java 代码中使用。


(请注意,这不是一个“空语句”。空语句 (JLS 14.6) 出现在允许语句的语法上下文中。空语句的存在可以改变代码的含义;例如,如果 (a == b) ; c(); vs if (a == b) c(;


答案 2

在早期,允许这样做是C /C++程序员更熟悉Java的方式之一。这种熟悉感对于Java的采用非常重要。

以下是它在语法上的工作方式。

在顶级类之后,它之所以有效,是因为编译单元包含以下序列,根据 JLS 7.3:

CompilationUnit:
 PackageDeclaration(opt) ImportDeclarations(opt) TypeDeclarations(opt)

根据 JLS 7.6,类型声明是以下任一项:

TypeDeclaration:
   ClassDeclaration
   InterfaceDeclaration
   ;

在嵌套在其他类中的成员类之后,它之所以有效,是因为分号可以是类成员声明,根据 JLS 8.1.6:

ClassMemberDeclaration:
    FieldDeclaration
    MethodDeclaration
    ClassDeclaration    
    InterfaceDeclaration
    ;

在局部类之后,在方法内部,它的工作原理是分号可以是空语句,根据 JLS 14.6:

EmptyStatement:
    ;