-3

This is a revised version of my previous question.

When using else-if as a shortcut, I'm not exactly sure why, syntax wise, it performs the same functionality as nesting if-else statements. Let's say you have the following:

int score = 80;
if(score < 80) {
  System.out.println("C Grade");
} else if(score < 90) {
  System.out.println("B Grade");
} else if(score < 100) {
  System.out.println("A Grade");
}

If I add some indentation, I get something similar to:

if(score < 80) {
  System.out.println("C Grade");
} else 
  if(score < 90) {
    System.out.println("B Grade");
  } else 
    if(score < 100) {
      System.out.println("A Grade");
    }

This evaluates the same as writing nested if-else statements as such:

if(score < 80) {
    System.out.println("C Grade");
} else { 
    if(score < 90) {
        System.out.println("B Grade");
    } else { 
        if(score < 100) {
        System.out.println("A Grade");
        }
    }
}

I see a major difference, however. In the third code snippet, the "else" statement has brackets, and the remaining if-else statements are nested inside those brackets. While in the first scenario, there are no encapsulating brackets. So why does the first idea of else-if work, if I seemingly need to have brackets when nesting if-else statements? I thought that a lack of brackets with control flow statements such as if, else, while, etc. cause the compiler to only evaluate the following line, such as:

if(condition)
    System.out.println("A");
    System.out.println("B");
//only prints "A"
Community
  • 1
  • 1
rb612
  • 5,280
  • 3
  • 30
  • 68
  • else-if in Java behaves as else followed by if - intensionally. Lack of brackets does NOT evaluate the following line, but the following statement. Since if (or if else) is a statement it is pretty consistent. – CoronA Jan 15 '17 at 07:31
  • 1
    A tip when asking questions - making assertions in your title (such as positing that `else` statements are inconsistent) will lead to downvotes as people are likely to disagree with your assertion rather than try to help you. Instead focus on what you're really asking, e.g. "Can you help me understand the syntax of `else if` statements?" which will encourage aid, rather than downvotes. – dimo414 Jan 16 '17 at 22:41

3 Answers3

2

If there are no brackets, the following statement is used, not just the following line.

An if-statement consists of

if (<condition>) <statement> else <statement>

It does not matter if it's written on several lines. In general, line breaks can occur in Java everywhere where white space is allowed without changing the meaning (the only exceptions are within string literals and one line comments).

Henry
  • 42,982
  • 7
  • 68
  • 84
  • Ah! So the if and the else are all one statement? So when an "else" does not have brackets, it will look at the first "pair" of an if and else, and evaluate that? – rb612 Jan 15 '17 at 08:13
  • Yes. The `else` is always matched to the nearest `if`. – Henry Jan 15 '17 at 08:17
  • just to clarify, an if-else grouping is one statement? But within that, there are statements corresponding to "if" and "else"? – rb612 Jan 16 '17 at 07:17
  • @rb612 Not sure I understand what you mean. The nested statements can be arbitrarily complex (containing loops, ifs, ...). – Henry Jan 16 '17 at 10:13
1

First off, note that if and else always apply to the single statement that follows them. You can use { } to group multiple statements into a single compound statement, but the conditional then applies to the single { ... } statement.

Consider these two equivalent statements:

if (foo) {
  bar();
}

if (foo)
  bar();

In the first the if applies to the { } block (which contains bar();) while in the second it applies directly to the bar(); statement. What may not be immediately apparent is that { } is not the only way to create a compound statement. In fact, if is another compound expression, hence it can be the direct child of another if or else statement. For instance:

if (foo)
  if (bar) {
    baz();
  }

Is perfectly valid (if hard to read) and is equivalent to:

if (foo) {
  if (bar) {
    baz();
  }
}

The same concept is true of else - whatever statement follows it will be applied if the preceding conditional is false, even if that statement is itself a compound statement!

if (foo) {
  bar();
}
else
  if (baz) {
    biff();
  }

The else applies to the whole if (baz) block, and since it's only a single (compound) statement there's no need for an additional { } block.

The exact grammar is specified in JLS §19, and the grammar of the different forms of the if statement are detailed in JLS §14.9. Notice that there's no mention of else if because it's not a formal part of the language, simply a (intentional) consequence of the grammar.


All of that said, the real reason we don't format the code the way you're describing is simply because it's harder to read. It's much simpler to think of else if as a single keyword and indent your code accordingly. Some other languages (e.g. Python) use a single keyword like elif to simplify the grammar, but it's not really necessary.

Community
  • 1
  • 1
dimo414
  • 47,227
  • 18
  • 148
  • 244
  • Thank you!! This is very helpful. I'm trying to completely understand - with my second statement that I wrote in my question, are lines 4 to the end all one statement then? From `if(score < 90)` to the end – rb612 Jan 15 '17 at 08:09
  • Well, yes and no :) the `if`and `else` bodies of an `if-else` statement are themselves statements, and therefore can also be `if-else` statements. In other words each of your examples *is* a single statement - but those statements then consist of sub-expressions which are also valid statements. – dimo414 Jan 15 '17 at 08:19
  • I added some links to the JLS in my answer, in case that's helpful. – dimo414 Jan 15 '17 at 08:25
  • Thanks again! So just to clarify, because the "else" will look at the next statement, it will look at both the next if and the else statement together as one statement? Because if they weren't one statement, then the "else" would just evaluate the nested "if" and not the "else" – rb612 Jan 15 '17 at 23:03
  • I don't know how helpful it is to think in terms of where a keyword will "look". Instead try to think in terms of the grammar that defines Java syntax. The `if` keyword must be followed by a boolean expression, then by a statement. It can optionally then be followed by an `else` and another statement. Since this is, itself, a valid statement it's possible to nest conditional statements inside one another. In contrast it's not possible (according to the grammar) for an `else` to appear anywhere other than immediately after the body-statement of an `if`. – dimo414 Jan 16 '17 at 01:07
  • I'm just wondering though the idea that a lack of brackets causes java to only evaluate the following statement. So is the "following statement" comprised of the if and else together? This is the only way I can see the code properly executing – rb612 Jan 16 '17 at 01:10
  • Because if the if and else were separate statements that follow the "else", then you would need brackets to execute both. – rb612 Jan 16 '17 at 01:14
  • That's right - `if () ` and `if () else ` are both valid syntax, while `else ` (on its own) is not valid. – dimo414 Jan 16 '17 at 18:33
1

Brackets are not a flow control mechanism. They are primarily a statement grouping mechanism.

The syntax for a simple if else statement is:

'if' '(' expression ')' statement 'else' statement

A 'statement' can be an assignment statement, a method call, a nested if and so on. But a 'statement' is not two statements, or three, or ...

This is where { } comes into it, because

'{' statement-list '}'

is actually statement according to the Java syntax rules. By using the curly brackets, you are grouping (possibly) many statements into a single statement.

If you apply this knowledge to your examples, the "mysterious" behavior that you think you are seeing will turn out to be simple and straight-forward.

For the record, it is recommended that you always use { } blocks with if statements and loops, because it makes your code easier to read.


I thought that a lack of brackets with control flow statements such as if, else, while, etc. cause the compiler to only evaluate the following line.

You have drawn an incorrect conclusion. In the Java language, it is (pretty much) irrelevant to the meaning of your code where you put the line breaks. The only restriction is that you can't put line breaks in the middle of tokens like keywords, operators, identifiers and literals. (And a line break ends a // comment.)

By the way, trying to learn a programming language by reading it like text and guessing the syntax is a bad approach. You will all sorts of incorrect ideas. A better approach is to read a good text book, or the language's official tutorial material.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Thank you Stephen, I agree. I've learned Java for years now and this idea just popped up as I'm so used to using else if but just started questioning why it works. So therefore is everything in my second code snippet, from `if(score < 90)` to the end all one statement? – rb612 Jan 15 '17 at 08:11
  • So to make sure I fully understand, if Java's "else" block without curly brackets evaluates only the next statement, if it's followed by an if-else, the "if" and the "else" are considered to be one statement? Or else, Java wouldn't evaluate the "else" as part of the nesting, correct? – rb612 Jan 16 '17 at 07:21
  • It is simpler than that. After the `else` there should be a statement. It could be a simple method call or assignment statement. It could be another `if` statement. It could be a block statement. It just has to be a statement. – Stephen C Jan 16 '17 at 07:24
  • Thanks for your response. But if you don't have curly braces, and thus Java will evaluate only the next statement, won't it simply evaluate the if portion, and not the "else" portion, because those are separate statements? Or is the if and else together one statement? That's where I'm confused. – rb612 Jan 16 '17 at 07:26
  • Nope. An else is not a statement. The statement following the else is *part of* the `if ... else ... ` statement. A statement can *contain* other statements – Stephen C Jan 16 '17 at 07:33
  • Okay so to clarify, "if ... else ..." is all one statement which contain statements? – rb612 Jan 16 '17 at 08:00