11

我想这更多的是关于语言理论的问题。为什么 main 中的第一个语句是合法的,而第二个不是?他们不认为是同一件事吗?

public class Main {
        public static void main(String[] args) {
                foo();
                0;
        }
        public static int foo(){
                return 0;
        }
}
4

2 回答 2

19

Java 限制了所谓的“表达式语句”中允许的表达式类型。只允许具有潜在副作用的有意义的表达式。0;它不允许像or之类的语义上无意义的语句a + b;。它们只是被排除在语言语法之外。

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

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

return;
foo();    // unreachable statement

C 和 C++ 对这一切都相对放任自流。想写什么就写什么;他们没有时间照顾你。


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

某些类型的表达式可以通过在它们后面加上分号来用作语句。

ExpressionStatement:
    StatementExpression ;

StatementExpression:
    Assignment
    PreIncrementExpression
    PreDecrementExpression
    PostIncrementExpression
    PostDecrementExpression
    MethodInvocation
    ClassInstanceCreationExpression

表达式语句通过对表达式求值来执行;如果表达式有值,则丢弃该值。

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

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

(void)... ;  // incorrect!

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

于 2013-05-16T23:43:03.813 回答
0

在第一个语句中,您实际上是在调用一个函数,而第二个语句没有给出任何值。如果要处理返回值,则需要调用返回类型的变量

例如:

public class Main {

    public static void main(String[] args) {
        int n = foo();
    
         //do whatever you want with return 
    }

    public static int foo() {
        return 0;
    }
}
于 2019-02-23T07:39:54.530 回答