Tenho uma pergunta maluca sobre os switches Java.
int key = 2;
switch (key) {
case 1:
int value = 1;
break;
case 2:
value = 2;
System.out.println(value);
break;
default:
break;
}
Cenário 1 - Quando o key
é dois, ele imprime com sucesso o valor como 2.
Cenário 2 - Quando vou comentar value = 2
, case 2:
ele grita dizendo que o valor da variável local pode não ter sido inicializado .
Questões:
Cenário 1: Se o fluxo de execução não vai para case 1:
(quando o key = 2
), como ele sabe o tipo da variável de valor como int
?
Cenário 2: Se o compilador conhece o tipo da variável de valor como int
, então ele deve ter acessado a int value = 1;
expressão em case 1:
. (Declaração e Inicialização). Então, por que faz isso sqawrk Quando eu vou comentar value = 2
no case 2:
, dizendo que o O valor variável local pode não ter sido inicializado .
java
scope
initialization
switch-statement
declaration
namalfernandolk
fonte
fonte
Respostas:
As declarações switch são estranhas em termos de escopo, basicamente. Da seção 6.3 do JLS :
No seu caso,
case 2
está no mesmo bloco quecase 1
e aparece depois dele, emboracase 1
nunca seja executado ... então a variável local está no escopo e disponível para escrita, apesar de você logicamente nunca "executar" a declaração. (Uma declaração não é realmente "executável", embora a inicialização seja.)Se você comentar a
value = 2;
atribuição, o compilador ainda saberá a qual variável você está se referindo, mas você não terá passado por nenhum caminho de execução que atribua um valor a ela, e é por isso que você obtém um erro como faria quando tentasse leia qualquer outra variável local não definida definitivamente.Eu recomendo fortemente que você não use variáveis locais declaradas em outros casos - isso leva a um código altamente confuso, como você viu. Quando introduzo variáveis locais em instruções switch (o que tento fazer raramente - os casos devem ser muito curtos, de preferência), geralmente prefiro introduzir um novo escopo:
Acredito que isso seja mais claro.
fonte
A variável foi declarada (como um int), mas não inicializada (com um valor inicial atribuído). Pense na linha:
Como:
A
int value
parte diz ao compilador em tempo de compilação que você tem uma variável chamada valor que é um int. Avalue = 1
parte o inicializa, mas isso acontece em tempo de execução e não acontece de forma alguma se esse branch do switch não for inserido.fonte
De http://www.coderanch.com/t/447381/java-programmer-SCJP/certification/variable-initialization-within-case-block
fonte
Com a integração de JEP 325: Switch Expressions (Preview) em compilações de acesso antecipado JDK-12. Existem certas mudanças que podem ser vistas na resposta de Jon -
Escopo da variável local - As variáveis locais nos casos de switch podem agora ser locais para o próprio caso em vez de todo o bloco de switch . Um exemplo (semelhante ao que Jon tentou sintaticamente também) considerando a
Day
classe enum para obter mais explicações:Switch Expressions - Se a intenção é atribuir um valor a uma variável e então fazer uso dele, uma vez pode fazer uso das expressões switch. por exemplo
fonte
Esta explicação pode ajudar.
fonte
Especificação Java:
https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.11
https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.7
Declarações rotuladas:
Em outras palavras, caso 1, caso 2 são rótulos dentro da instrução switch. as instruções break e continue podem ser aplicadas aos rótulos.
Como os rótulos compartilham o escopo da instrução, todas as variáveis definidas dentro dos rótulos compartilham o escopo da instrução switch.
fonte