【问题标题】:Why does code with successive semi-colons compile?为什么带有连续分号的代码可以编译?
【发布时间】:2012-05-08 02:23:57
【问题描述】:

根据我的科学 Java 实验,int x = 0; 等价于int x = 0;; 等价于int x = 0;;;;;;;;;;;;;;;

  1. 为什么 Java 允许这样做?有实际应用吗?
  2. 这些都是空语句吗?它们实际上是否在运行时占用了任何额外的处理时间? (我会假设它们只是优化了?)
  3. 其他语言也这样做吗?我猜它是从 C 继承的东西,就像 Java 中的很多东西一样。这是真的吗?

【问题讨论】:

标签: java


【解决方案1】:

多余的分号被视为空语句。空语句什么都不做,这就是 Java 不抱怨它的原因。

【讨论】:

    【解决方案2】:

    正如 Jake King 所写,您可以生成空语句以在循环中不执行任何操作:

    while (condition);
    

    但为了清楚起见,你会写

    while (condition)
        ;
    

    甚至更好:

    while (condition)
    /** intentionally empty */
        ;
    

    甚至更好,正如 Michael Kjörling 在评论中指出的那样,

    while (condition)
    {
        /** intentionally empty */
    }
    

    更多时候,你会在 for 语句中看到它的无限循环:

    for (;;)
    

    或者只有一个空语句

    for (start;;) 
    for (;cond;) 
    for (;;end) 
    

    您可以做的另一件事是,编写一个程序,一次用一个分号,一次用两个分号:

    public class Empty
    {
        public static void main (String args[])
        {
            System.out.println ("Just semicolons");;
        }
    }
    

    编译它,并运行列出字节码的大小(相同)并对字节码(相同)执行 md5sum。

    所以在语义没有改变的情况下,它显然被优化掉了,至少对于 1.6-Oracle 编译器我可以这么说。

    【讨论】:

    • C 甚至可以做while(condition); 这也是作为语句执行的。
    • 在极少数情况下需要一个空的while循环语句块,我发现最好将它写成while(condition) { }的化身而不是while(condition);(抛出的评论是另一个这样做的好方法)。分号很容易被忽略,但大括号是明确的。 另外,虽然我不会因为有人可能不知道而说不使用语言功能,但看似错误的语句终止符是一个心理障碍,通常最好避免这种情况,以便于理解代码。
    【解决方案3】:

    是的,它们是空语句,根本不做任何事情。它们由编译器优化,但在某些情况下,这个空语句实际上做了一些事情,与一组空括号 ({}) 做同样的事情。它们继承自 C 语法,但在 Java 中很少使用。在 C 中,有时这样做很有用:

    while (condition);
    

    这将循环直到condition 为假,从而阻止代码继续进行。然而,这在现代代码中是不鼓励的,并且不应该在 Java 中真正使用。但是,空语句确实算作语句,只是无用的语句,所以构造如下:

    if (condition);
        doSomething();
    

    ....可能会导致有些莫名其妙的结果。 if 语句将调用空语句,而不是方法,因此将总是调用方法。请记住一个警告。

    【讨论】:

    • +1,但我很确定编译器会优化(删除)空语句。
    • @Jeremy 不是这样,空语句被留在了,因为它们实际上是在做某事。他们在技术上算作陈述,他们什么也不做。这与完全删除语句本身不同。
    • 编译 these two classes 会产生完全相同的字节码(类名除外)。 while (true); 末尾的分号不是空语句。它在没有块的情况下终止 while 循环。
    • @Jeremy 够公平的。看来我错了。诚然,我不知道我从哪里得到这些信息,但在某个地方,有人提供了虚假信息。哦,好吧。
    • @Jeremy 我没有,对不起,如果听起来像我。感谢您的指正。 :)
    【解决方案4】:

    需要注意的一点是,如果你这样做:

    public int foo()
    {
        return(0);;
    }
    

    编译器会/可能会抱怨无法访问的语句,因为返回后有一个空语句。至少在 Oracle 的 1.6 sdk 中是这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多