打捞回复帖。嗯这无聊的语法问题…
原文地址:[url]http://www.iteye.com/topic/1064881?page=6#2136913[/url]
[quote="lion1354"]好吧看代码,把下面两段代码粘到eclipse中你就会知道了
至于原因请高人来回答[/quote]
嘛,这个的理由很简单:因为局部变量声明不是“语句”。
这是Java语言规范里非常搞笑的一个地方:请看[url=http://java.sun.com/docs/books/jls/third_edition/html/syntax.html#18.1]Java语言规范第三版18.1[/url]所指定的语法规则中的几条:
方法体必须是一个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分支上还是不能单独放一个局部变量声明 =_=|||
想看源码的请点:
[url]http://hg.openjdk.java.net/jdk6/jdk6/langtools/file/tip/src/share/classes/com/sun/tools/javac/tree/JCTree.java[/url]
原文地址:[url]http://www.iteye.com/topic/1064881?page=6#2136913[/url]
[quote="lion1354"]好吧看代码,把下面两段代码粘到eclipse中你就会知道了
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");
}
}
上面的编译错误
至于原因请高人来回答[/quote]
嘛,这个的理由很简单:因为局部变量声明不是“语句”。
这是Java语言规范里非常搞笑的一个地方:请看[url=http://java.sun.com/docs/books/jls/third_edition/html/syntax.html#18.1]Java语言规范第三版18.1[/url]所指定的语法规则中的几条:
Block:
{ BlockStatements }
BlockStatements:
{ BlockStatement }
BlockStatement :
LocalVariableDeclarationStatement
ClassOrInterfaceDeclaration
[Identifier :] Statement
LocalVariableDeclarationStatement:
[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 : Statement
MethodBody:
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分支上还是不能单独放一个局部变量声明 =_=|||
想看源码的请点:
[url]http://hg.openjdk.java.net/jdk6/jdk6/langtools/file/tip/src/share/classes/com/sun/tools/javac/tree/JCTree.java[/url]