【问题标题】:Java: Not a statementJava:不是声明
【发布时间】:2013-05-12 00:57:21
【问题描述】:

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

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

【问题讨论】:

标签: java semantics


【解决方案1】:

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

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

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

return;
foo();    // unreachable statement

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


引用Java Language Specification, §14.8 Expression Statements:

某些类型的表达式可以用作语句,如下所示 他们用分号。

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 节)。

【讨论】:

    【解决方案2】:

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

    例如:

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

    【讨论】:

    • 这个答案没有解决这个问题。这个问题是关于如何以任何方式修复代码。问题是要解释为什么当时的语言允许做一件事,而另一件类似的事情会产生编译错误。
    • @Lii 我已经修改了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 2011-03-23
    • 2017-07-26
    • 1970-01-01
    • 2013-02-15
    • 2021-09-18
    相关资源
    最近更新 更多