1

如果我尝试在声明语句以外的语句上使用大括号初始化数组,为什么会出现编译错误

class Demo {
    public static void main(String[] args) {
        String[] myName;
            myName = {"AA", "BB", "CC"};
        for(String s: myName) {
            System.out.print(s + " ");
        }
    }
}

只在声明语句中使用大括号进行初始化有什么意义?

demo.java:4: error: illegal start of expression
                myName = {"AA", "BB", "CC"};
                         ^
demo.java:4: error: not a statement
                myName = {"AA", "BB", "CC"};
                          ^
demo.java:4: error: ';' expected
                myName = {"AA", "BB", "CC"};
                              ^
demo.java:5: error: illegal start of type
                for(String s: myName) {
                ^
demo.java:5: error: ')' expected
                for(String s: myName) {
                            ^
demo.java:5: error: <identifier> expected
                for(String s: myName) {
                                    ^
demo.java:10: error: class, interface, or enum expected
}
^
7 errors
4

2 回答 2

7

如果我尝试在声明语句以外的语句上使用大括号初始化数组,为什么会出现编译错误

因为基本上在 Java 中这样做是无效的。编译器只是执行 Java 语言规范的规则。您需要指定数组类型:

myName = new String[] { ... };

来自Java 语言规范,第 10.6 节

数组初始值设定项可以在声明中指定(第 8.3 节、第 9.3 节、第 14.4 节),或作为数组创建表达式的一部分(第 15.10 节)来创建数组并提供一些初始值。

声明的各个部分包括这个产生:

VariableInitializer:
    Expression
    ArrayInitializer

而数组创建表达式(第 15.10 节)是:

ArrayCreationExpression:
    new PrimitiveType DimExprs Dimsopt
    new ClassOrInterfaceType DimExprs Dimsopt
    new PrimitiveType Dims ArrayInitializer 
    new ClassOrInterfaceType Dims ArrayInitializer

DimExprs:
    DimExpr
    DimExprs DimExpr

DimExpr:
    [ Expression ]

Dims:
    [ ]
    Dims [ ]

之后:

只在声明语句中使用大括号进行初始化有什么意义?

我怀疑它在其他方面简化了语言规范。我同意看起来你应该能够做到这一点 - 你可能希望编译器能够从变量类型推断数组类型,就像它在声明时所做的那样。但请记住,一般来说,对于大多数语言来说,赋值运算符右侧的表达式类型不受赋值目标的影响。对于普通语句中的每个表达式的类型,在不参考同一语句中的其他表达式的情况下定义良好,通常在语言方面更简洁。

使用数组创建表达式修复代码相当容易,所以我会接受它。

于 2012-12-01T10:50:09.577 回答
5

The syntactically correct way to write what you're trying to write is:

myName = new String[]{"AA", "BB", "CC"};

I suspect the reason Java doesn't allow omitting new String[] is that in many contexts there's no way for the compiler to figure out the desired type of the array from the types of the elements. Let's say you were allowed to write:

{1, 2, 3}

Is that int[], Integer[], Number[] or Object[]?

The only place where are you're allowed to omit new String[] is initializers, where the compiler already knows the array type.

于 2012-12-01T10:40:58.827 回答