为什么分号不是必需的,但在类定义结束时允许使用分号?
我正试图从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专家能帮助我。
好吧,我已经在课堂定义和其他相关问题中看到过Semicolons 。
提前致谢。
我编译并执行了为Java显示的程序片段,它们都有效。 任何人都可以解释为什么会这样吗?
这是允许的,因为Java语法说它是允许的; 见JLS 7.6 。
Java中类定义结尾的分号代表什么?
没有。 它是可选的“语法噪音”。
JLS解释如下:
额外的“;” 出现在编译单元中类型声明级别的标记对编译单元的含义没有影响。 Java编程语言中允许使用杂散分号,仅作为对习惯于放置“;”的C ++程序员的让步。 在课堂宣言之后。 它们不应该用在新的Java代码中。
(请注意,这不是一个“空语句”。空语句( JLS 14.6 )出现在允许语句的语法上下文中。空语句的存在可以改变代码的含义;例如if (a == b) ; c();
与if (a == b) c();
)
在早期,允许这是Java使C / C ++程序员更熟悉的方式之一。 这种熟悉程度对于采用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: ;
Java只为那些从C ++切换的人添加了这个!
在Java中,单个分号是一个几乎可以在任何地方编写的声明。 它的唯一目的是简化这些语言的过渡。
例如,Java中的以下内容也是正确的:
;;;;;;;;;; class X{ ;;;;;;;;;;;;;; } ;;;;;;;;;;;;;;;
分号被简单地视为空的声明,什么都不做。
以下是规范第7.6段的引用:
额外的“;” 出现在编译单元中类型声明级别的标记对编译单元的含义没有影响。 Java编程语言中允许使用杂散分号, 仅作为 对习惯于放置“;”的C ++程序员 的 让步。 在 课堂宣言之后。 它们不应该用在新的Java代码中。
所以你看,这真的只适合像你这样的人:)。
你甚至可以使用一行分号作为一个很好的视觉分离。 但是,我强烈建议不要这样做。 但它可能有利于吹牛的目的。 例如:
class X { // Member variables private int i; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; // Constructors X(){} ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; // Methods void foo(){} }
我认为这是从Cinheritance的跟随风格:
struct A { unsigned a; unsigned b; };
或者您可以使用:
struct A { unsigned a; unsigned b; }A1,A2;
我不熟悉Java,但是需要额外分号的原因是因为你可以在函数内部定义一个匿名类。 例如:
void routine(const int x, const int y) { class { public: int x; int y; } my_instance; my_instance.x = x; my_instance.y = y; // ... etc }
你通常会看到结构比使用类更多,以捕获大类的一些重要变量。
void f(const BigClass& big_class) { struct { std::string str; int i; } props; props.str = big_class.GetFilename(); props.i = big_class.GetID(); // etc... }