如果我尝试使用大括号初始化一个不是数组的变量,我会收到编译错误。
E.g:
public class test1 {
public static void main(String[] args) {
double a = {1.5,6.3};
}
}
使用“javac”,我收到此编译错误:
test1.java:13: error: illegal initializer for double
double a = {1.5,6.3};
^
1 error
然而,我正在学习Java语法,我找到了以下作品(来自The Java Language Specification):
VariableDeclarators:
VariableDeclarator
VariableDeclarators , VariableDeclarator
VariableDeclarator:
VariableDeclaratorId
VariableDeclaratorId = VariableInitializer
VariableDeclaratorId:
Identifier
VariableDeclaratorId [ ]
VariableInitializer:
Expression
ArrayInitializer
ArrayInitializer:
{ VariableInitializersopt ,opt }
根据这些规则,我可以成功编译上面的代码(我尝试使用编译器,使用jflex和.cup规范文件,其中指定了语法)。 为什么这可能?有什么我忽略的吗?
谢谢。
答案 0 :(得分:2)
问题是,是的,语法 是正确的,但没有任何意义。
"猪在天空中飞翔。"是一个语法英语句子,但它没有意义。
您编写了一个语法Java语句,但编译失败,因为编译不只是匹配语法,类型也必须匹配(在更多其他事情之中)。这里,=
的左侧是双类型变量,右侧是类型double[]
的表达式。这两种类型不可隐式转换,因此代码无法编译。
要成功编译,请尝试将double
更改为double[]
。
答案 1 :(得分:2)
使用语法,您可以成功解析您的代码,javac
也是如此(请注意javac
的错误消息并未说明" [预期",这将是它为解析错误产生的消息)。但是编译不仅仅涉及解析 - 它还涉及类型检查,当代码没有进行类型检查时,它就不会编译。
另一个例子,语法也允许int x = "lala";
。与您的示例一样,这会正确解析,但会被类型检查器拒绝。
程序输入良好的规则也是规范的一部分,但与语法分开。这些规则禁止double a = {1.5,6.3};
或int x = "lala";
等内容。
答案 2 :(得分:1)
在接受程序有效之前,编译器通常经历三个阶段:词法,句法和语义。符合形式语法规范的一段代码只是在词法和语法上,但不一定在语义上有效。在这种情况下,将值向量分配给标量变量并不具有语义意义,因此它在语义上无效。