58

Why does this first if compile well and the second fail?

if(proceed) {int i;} // This compiles fine.
if(proceed) int i;// This gives an error. (Syntax error on token ")", { expected after this token)
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
ironwood
  • 8,936
  • 15
  • 65
  • 114
  • 2
    Related : [Object creating statement in Java doesn't allow to use a single-line loop. Why?](http://stackoverflow.com/questions/8145663/object-creating-statement-in-java-doesnt-allow-to-use-a-single-line-loop-why) – Lion Jul 17 '12 at 21:30

5 Answers5

73

Because the language spec says so:

http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html

A declaration introduces an entity into a program and includes an identifier (§3.8) that can be used in a name to refer to this entity. A declared entity is one of the following:
...
A local variable, one of the following:
* A local variable declared in a block (§14.4)
* A local variable declared in a for statement (§14.14)

Your first example is declaring i inside a block (denoted by curly braces). Your second isn't, nor is it a for statement.

Edited to add: Which just makes commons sense. If it were allowed, it would be useless. It would immediately fall out of scope.

JustBeingHelpful
  • 18,332
  • 38
  • 160
  • 245
Brian Roach
  • 76,169
  • 12
  • 136
  • 161
  • 1
    I know that it is useless. But I wanna knew what's the rule behind it. And I got your point Brian. Thanx. – ironwood Feb 09 '12 at 07:13
  • 5
    The JLS (Java Language Spec) is always the place to go :) Honestly it's amazing some of the stuff you learn just reading though parts of it in your spare time; I know I've learned a lot that I wouldn't have otherwise known. – Brian Roach Feb 09 '12 at 07:17
  • 2
    Actually the second statement would declare the local variable in the block that contains the `for` statement, so this section of the JLS doesn't apply. Daniel's answer points to the real reason why this syntax is invalid. – Joni Feb 09 '12 at 08:27
  • 1
    @JoniSalonen - It would appear you don't understand what a block is, or the difference between an `if` statement and a `for` statement? Daniel's answer is the same as mine - a variable declaration is not valid in an `IfThenElseStatement`; it is only valid in a `Block` or the header of a `ForStatement`. The OP's first example is a `StatementWithoutTrailingSubstatement` (`IfThenElseStatement`) that contains a `Block`. His second is a bare `IfThenElseStatement`. – Brian Roach Feb 09 '12 at 14:48
  • 2
    If you've been downvoted it wasn't me. I'm only saying that the section of JLS you quote is not the decisive one here: you are quoting is the definition of the term "declared entity." Applying that definition `int i;` is a declaration--it declares the entity `i`--but that alone doesn't make it illegal. To see why it's illegal you have to refer to the definition of `IfThenStatement`. And yes, it's a silly hair-splitting difference. – Joni Feb 09 '12 at 15:12
  • Replying to your edited comment: Sure, but to find that out you had to first read the definitions of `IfThenStatement` and `Statement` in §14.5, you couldn't make that argument based on the section §6.1 alone. – Joni Feb 09 '12 at 15:26
  • @JoniSalonen - I'm going to agree it's a hair splitting difference ( ;) ), but I get your point. I honestly do believe that the two items in 6.1 provide enough information to state that the language spec says the OPs second example isn't valid, and if you really want to know more you can follow the trail to section 14. – Brian Roach Feb 09 '12 at 16:06
54

From the Java Language Spec.

    Block:
            { BlockStatementsopt }

    BlockStatements:
            BlockStatement
            BlockStatements BlockStatement

    BlockStatement:
            LocalVariableDeclarationStatement
            ClassDeclaration
            Statement

and

    IfThenStatement:
            if ( Expression ) Statement

It seems that int i is a LocalVariableDeclarationStatement, not a Statement. So it doesn't work.

Christophe Roussy
  • 16,299
  • 4
  • 85
  • 85
Daniel
  • 27,718
  • 20
  • 89
  • 133
  • 16
    +1. This is the real reason the syntax is invalid. The JLS section on declarations mentioned in Brian's answer is related but not the real reason. – Joni Feb 09 '12 at 08:24
12

This is because it would not be useful code. If you have an if-statement without curly braces ({}), only the first line / statement after the if is executed. So if you only declare a local variable, it cannot be used anywhere else. So declaring it is absolutely superfluous.

if(proceed){
int i= 0;
 // variable i can be used here
//...
}

if (proceed) int i; // i can not be used anywhere as it is a local variable
steffinchen
  • 497
  • 4
  • 12
3

if(proceed) int i;

If we use if statement without braces it will execute only first line with the if for the conditional manner. Other lines will execute normally.

This is compilation fail, because local variable declaration happen with conditional manner and compiler assume it is not reachable with the false statement.

If you use a curly braces, then variable declaration and use of local variable within the block and hence compiler assume it is reachable code. Then no compiler errors.

  • The compiler *defines* that it is not reachable, and because its scope has ended, not because the statement may be false. – user207421 Sep 24 '17 at 22:15
0

As in Java / C++ ,if we write if without braces ,only 1st statement is executed In this case , variable i is of no use. You are declaring it in if statement and its scope ends after this statement , which is useless

In C++ , this is allowed ,but Java doesn't allow this

abhi120
  • 278
  • 4
  • 15