Java:不是声明

Sky*_*ler 10 java semantics

我想这更像是一个关于语言理论的问题而不是其他任何问题.为什么第一个声明是主要法律,第二个声明不是?他们不认为是同一件事吗?

public class Main {
        public static void main(String[] args) {
                foo();
                0;
        }
        public static int foo(){
                return 0;
        }
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*ica 15

Java限制了所谓的"表达式语句"中允许的表达式类型.只允许有潜在副作用的有意义的表达.它不允许语义无意义的陈述,如0;a + b;.他们只是被排除在语言语法之外.

foo()can 这样的函数调用通常会产生副作用,因此它不是无意义的语句.编译器不会深入检查主体foo()以检查它是否确实发生了任何事情.调用函数可能会产生副作用,因此它在语法上是有效的.

这反映了C/C++和Java之间的哲学差异.Java禁止各种导致死代码或无意义代码的构造.

return;
foo();    // unreachable statement
Run Code Online (Sandbox Code Playgroud)

关于这一切,C和C++相对自由放任.写下你想要的任何东西 他们没有时间照顾你.


引用Java语言规范,§14.8表达式语句:

某些类型的表达式可以用分号跟随它们作为语句.

ExpressionStatement:
    StatementExpression ;

StatementExpression:
    Assignment
    PreIncrementExpression
    PreDecrementExpression
    PostIncrementExpression
    PostDecrementExpression
    MethodInvocation
    ClassInstanceCreationExpression
Run Code Online (Sandbox Code Playgroud)

通过计算表达式来执行表达式语句; 如果表达式具有值,则丢弃该值.

当且仅当表达式的评估正常完成时,表达式语句的执行才能正常完成.

与C和C++不同,Java编程语言只允许某些形式的表达式用作表达式语句.请注意,Java编程语言不允许"强制转换为void" - void不是类型 - 因此编写表达式语句的传统C技巧如:

(void)... ;  // incorrect!
Run Code Online (Sandbox Code Playgroud)

不起作用.另一方面,Java编程语言允许表达式语句中所有最有用的表达式,并且它不需要用作表达式语句的方法调用来调用void方法,因此几乎不需要这样的技巧.如果需要技巧,可以使用赋值语句(第15.26节)或局部变量声明语句(第14.4节).