【问题标题】:Why is "new String();" a statement but "new int[0];" not?为什么是“新字符串();”一个声明,但“新 int [0];”不是?
【发布时间】:2021-07-10 23:47:38
【问题描述】:

我只是随机尝试查看new String(); 是否会编译并且它确实可以编译(因为根据 Oracle 的 Java 文档“表达式、语句和块”,有效的语句类型之一是“对象创建”),

但是,new int[0]; 给了我一个“不是声明”的错误。

这有什么问题?我不是用new int[0]创建一个数组对象吗?

编辑:

为了澄清这个问题,下面的代码:

class Test {
    void foo() {
        new int[0];
        new String();
    }
}

new int[0]; 上导致编译器错误,而new String(); 本身正常的。为什么一个不能接受,一个可以?

【问题讨论】:

  • 这不是 Java 中您想要做的正确语法
  • 请展示完整个例子——即,有足够的代码来测试编译这些行。
  • 语法更像:int[] intArray = new int[]{0};
  • 致闭门者:这既不需要细节也不需要清晰;我知道这个问题听起来很奇怪,但它是正确的。具体来说,class X { void foo() { new int[0]; }} 是编译错误,而void foo() { new String(); }} 不是。一旦它被打开,我会提供一个答案。
  • @KarlKnechtel - 这很容易。尝试编译一个类,其中main() 的整个主体为new String();,然后尝试将主体为new int[0];。你不觉得这有点有趣吗?

标签: java syntax


【解决方案1】:

原因是规范设计过度。

表达式不是有效语句背后的想法是它们什么都不做。 5 + 2; 自己什么都不做。您必须将其分配给某物,或者将其传递给某物,否则为什么要写它?

但也有例外: 就其自身而言,会(或可能会)产生副作用的表达式。例如,虽然这是非法的:

void foo(int a) {
    a + 1;
}

这不是:

void foo(int a) {
    a++;
}

这是因为,就其本身而言,a++ 并不是完全没用,它实际上会改变一些东西(通过这样做来修改 a)。实际上,如果自己产生价值的行为会导致其他事情发生,那么“忽略价值”(你在第一个 sn-p 中什么都不做 a + 1)是可以接受的:毕竟,也许这就是你所追求的一直以来。

因此,调用方法也是一种合法的表达式语句,实际上调用方法(即使是不返回void 的方法)而忽略返回值是很常见的。对于 void 方法,这是调用它们的唯一合法方式,甚至。

构造函数在技术上是方法,可能有副作用。如果这种方法是极不可能的,而且代码风格非常糟糕:

void doStuff() {
    new Something();
}

是“明智的”代码,但它在理论上可以写出来,尽管它可能很糟糕:Something 类的构造函数可能会做一些有用的事情,也许这就是你想做的全部这里:让构造函数运行,做有用的事情,然后取出创建的对象并立即将其扔进垃圾箱。奇怪,但是,好吧。你是程序员。

对比:

new Something[10];

这是不同的:编译器知道数组“构造函数”的作用。它所做的是没什么用处 - 它创建一个对象并返回对该对象的引用,这就是发生的所有。如果您然后立即将引用扔进垃圾中,那么整个操作完全是浪费时间,而且您肯定不打算对这种奇怪的语句做任何有用的事情,所以编译器设计者认为最好直接禁止你不要写它。

这种“哦,天哪,代码没有意义,因此我不会编译它”是非常有限的,并且大部分是原始编译器规范的过时方面;它从未更新过,这不是一个相信代码是明智的好方法;市面上有各种各样的 linter 工具,它们可以更进一步地找到你不可能正确的代码,所以如果你关心这类事情,那就投资学习这些。

尽管如此,java 1.0 规范已经包含了这些东西,并且没有特别好的理由放弃 java 规范的这方面,因此,它仍然存在,并且构造一个新数组不是有效的 ExpressionStatement。

正如JLS §14.8 所述,具体而言,ClassInstanceCreationExpression 位于有效的表达式语句列表中。点击那个词链接到ClassInstanceCreationExpression的定义,你会发现它特指调用构造函数,而不是是数组构造。

因此,JLS 是特定的并且需要这种行为。 javac 只是遵循规范。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多