首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

答复: 单命令行上,if 必须加"{}" 的有关问题

2012-10-28 
答复: 单命令行下,if 必须加{} 的问题打捞回复帖。嗯这无聊的语法问题…原文地址:http://www.iteye.com/to

答复: 单命令行下,if 必须加"{}" 的问题
打捞回复帖。嗯这无聊的语法问题…
原文地址:http://www.iteye.com/topic/1064881?page=6#2136913

public class Test{public static void main(String[] args){if (true){String i = new String("Test");}}}上面的编译正确

public class Test{public static void main(String[] args){if (true)String i = new String("Test");}}
上面的编译错误

至于原因请高人来回答
嘛,这个的理由很简单:因为局部变量声明不是“语句”。
这是Java语言规范里非常搞笑的一个地方:请看Java语言规范第三版18.1所指定的语法规则中的几条:
Block:        { BlockStatements }BlockStatements:        { BlockStatement }BlockStatement :        LocalVariableDeclarationStatement        ClassOrInterfaceDeclaration        [Identifier :] StatementLocalVariableDeclarationStatement:        [final] Type VariableDeclarators   ;Statement:        Block        assert Expression [ : Expression] ;     if ParExpression Statement [else Statement]     for ( ForControl ) Statement     while ParExpression Statement     do Statement while ParExpression   ;     try Block ( Catches | [Catches] finally Block )     switch ParExpression { SwitchBlockStatementGroups }     synchronized ParExpression Block     return [Expression] ;     throw Expression   ;     break [Identifier]     continue [Identifier]        ;        StatementExpression ;        Identifier   :   StatementMethodBody:        Block

方法体必须是一个block。
Block是由花括号包围的零或多个BlockStatement。
BlockStatement可以是局部变量声明,或者类/接口声明(注:这样的类或接口被称为“局部类”(local class)“局部接口”(local interface)),或者是可选带label的语句Statement。
语句有若干中可能,其中一种是if语句;if语句的then分支必须是一个Statement。

关注点是:LocalVariableDeclarationStatement虽然叫做“Statement“,但在语法规则中它却不是一种”Statement“。所以说根据这个规则,局部变量声明就不是语句,自然也就不能单独出现在if的then分支位置上。被花括号包围起来的话它就是一个Block了,而Block是Statement的一种所以没问题。

槽点:叫做“语句”但却不是语句的局部变量声明。

顺带一提,NS提醒我,在javac里代表局部变量声明的节点类型是JCVariableDecl,该类继承了代表了语句的JCStatement类;但是,javac仍然会按照语法规范来检查…所以if的then分支上还是不能单独放一个局部变量声明 =_=|||
想看源码的请点:
http://hg.openjdk.java.net/jdk6/jdk6/langtools/file/tip/src/share/classes/com/sun/tools/javac/tree/JCTree.javastatement: labeled-statement declaration-statement embedded-statementdeclaration-statement: local-variable-declaration ; local-constant-declaration ;if-statement: if ( boolean-expression ) embedded-statement if ( boolean-expression ) embedded-statement else embedded-statement
你看C#的规范里local-variable-declaration就是一种statement,只不过if的then和else分支的内容必须是embedded-statement,而local-variable-declaration不是一种embedded-statement。这跟Java的效果是一样的,但是至少它没有说“LocalVariableDeclarationStatement不是Statement”… 3 楼 william_ai 2011-06-01   恩,规范里这么规定,应该是从实际出发的,在if(true)后,只做定义一个变量(赋值)的操作,这个变量以后也不能用,这么定义变量没有意义。所以,就直接抛一个compile error。 4 楼 lwwin 2011-06-01   这个也被你挖出来了^-^ 5 楼 wyp12 2011-07-29   又多了一个小知识 6 楼 w445097062 2012-07-31   刚好和同事讨论这个问题,他坚持单命令行也加大括号,我坚持不加,个人习惯而已,随便;随后他用上面的例子来考我,翻到到了这篇文章,才解释得通

热点排行