15

So this is an odd one, I know the code itself is fairly useless, but what I'm wondering why I get the error:

I was writing some code, I had written this:

if(scan.hasNextInt())
    int row = scan.nextInt();

Wasn't thinking about variable scope at the time, obviously this is useless because I can't use row past the if anyway. What I don't get is why I got the error I did:

> javac hw.java
hw.java:25: '.class' expected
    int row = scan.nextInt();
        ^
hw.java:25: not a statement
    int row = scan.nextInt();
    ^    
hw.java:25: illegal start of expression
    int row = scan.nextInt();
            ^
hw.java:25: ';' expected
    int row = scan.nextInt();
                  ^

Now if I just modify that if check to:

if(scan.hasNextInt()) {
    int row = scan.nextInt();
}

It will compile fine. I was under the impression that if there was 1 line under the if the curly brackets were optional... clearly there are other considerations as well or both would either compile or fail.

Could someone explain to me, or point me to a document that explains why I can't declare a local variable under the if conditional without the curly brackets?


EDIT: Here's the full function:

public static char getinput() {
    System.out.println("Where do you want to go? (row column)");
    Scanner scan = new Scanner(System.in);
    if(scan.hasNextInt())
        int row = scan.nextInt();
    String input = scan.next();
    System.out.println(input);
    return 'a';    
}
Étienne
  • 4,773
  • 2
  • 33
  • 58
Mike
  • 47,263
  • 29
  • 113
  • 177

2 Answers2

26

If you have a if, for, while, do/while you must follow it with a statement. A declaration is not a statement.

From JLS 14.9 - The if Statement

IfThenStatement:
    if ( Expression ) Statement

IfThenElseStatement:
    if ( Expression ) StatementNoShortIf else Statement

IfThenElseStatementNoShortIf:
    if ( Expression ) StatementNoShortIf else StatementNoShortIf

I assume they do this because any variable you declare couldn't be used as it would be out of scope immediately (except the same declaration)

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • There it is. Thank you very much! – Mike Dec 19 '12 at 16:08
  • 1
    @PeterLawrey I'm not 100% sure, but this sentence from [JLS 14.4](http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.4) might be more relevant - "Every local variable declaration statement is _immediately contained by a block_." (emphasis added) – Kevin K Dec 19 '12 at 16:13
  • Changing the `if` to a `while` results in the same error, so actually I'm pretty sure that's the rule in effect – Kevin K Dec 19 '12 at 16:14
1

My guess is that a declaration isn't an executable statement and a declaration with an assignment is really broken into two different statements by the compiler, with the first statement (the declare) not being executable. An if requires an executable construct, either a block or an executable statement.

I know that I've not been able to put a breakpoint on a non-sassignment declaration statement in the Eclipse debugger. Probably the same underlying reason.

Chris Gerken
  • 16,221
  • 6
  • 44
  • 59