A resposta é não - a instrução if não é como uma instrução switch sem interrupção. Vamos começar com esta parte da sua pergunta:
se boolean_expression_1 fosse true, verificaria se boolean_expression_2 é true?
Podemos encontrar a resposta com este programa. O truque é que chamamos um método como nossa expressão booleana e usamos System.out.println () para ver se o método é executado. Dessa forma, sabemos se a expressão foi avaliada. Aqui está o programa:
public class IfElseExample {
private static boolean booleanExpression1() {
System.out.println("Expression 1 is being evaluated.");
return true;
}
private static boolean booleanExpression2() {
System.out.println("Expression 2 is being evaluated.");
return true;
}
public static void main(String[] args) {
if (booleanExpression1())
System.out.println("Statement 1 is executed");
else if (booleanExpression2())
System.out.println("Statement 2 is executed");
else
System.out.println("Default statement is executed");
}
}
Você verá que a segunda expressão booleana não é avaliada. Esse comportamento provavelmente se torna mais compreensível se você colocar alguns colchetes (o que é um bom hábito na maioria dos casos):
if (booleanExpression1()) {
System.out.println("Statement 1 is executed");
} else {
if (booleanExpression2()) {
System.out.println("Statement 2 is executed");
} else {
System.out.println("Default statement is executed");
}
}
É assim que o compilador visualiza sua cadeia de if original. Como você pode ver agora, o segundo "se" é uma declaração única e, como tal, não está no mesmo nível que a primeira declaração se. Se você encadear mais instruções if, elas ficam aninhadas ainda mais.
Você também perguntou por que a instrução switch precisa de uma instrução break. Isso ocorre porque a instrução switch não é implementada internamente com uma cadeia de instruções if (nem a instrução if com base nas instruções switch). Você pode esperar isso
switch(controllingExpression()) {
case 42: System.out.println("A");
case 43: System.out.println("B");
default : System.out.println("z");
}
é traduzido pelo compilador em algo como:
if (controllingExpression() == 42) {
System.out.println("A");
} else if (controllingExpression() == 43) {
System.out.println("B");
} else {
System.out.println("z");
}
Este não é o caso. Em vez disso, ele usa uma instrução skip oculta:
int x = numberOfStatementsToSkipFor(controllingExpression());
skip x // hidden skip the next x statements byte code instruction
System.out.println("A");
System.out.println("B");
System.out.println("z");
O método numberOfStatementsToSkipFor () retorna 0 para 42, 1 para 43 e 2 para todo o resto. Agora fica claro por que esse programa pode produzir
A
B
z
ou
B
z
ou apenas
z
mas nunca
A
B
sem o 'z'. Mas claramente seria bom se pudéssemos fazer isso. E podemos usar o break, que é traduzido em outra instrução skip. Então, se você colocar quebra em todos os ramos do caso
switch(controllingExpression()) {
case 42: {
System.out.println("A");
break;
}
case 43: {
System.out.println("B");
break;
}
default : System.out.println("z");
}
o compilador produzirá isso:
int x = numberOfStatementsToSkip(controllingExpression());
skip x; // hidden skip the next x statements byte code instruction
System.out.println("A");
skip 3; //"B" + skip + "z"
System.out.println("B");
skip 1;
System.out.println("z");