Pessoal, tava lendo o livro da Kathy Sierra. Lá tem as formas legais de se usar o switch e tal. Uma coisa não ficou clara pra mim, talvez eu tenha perdido algum detalhe, mas é o seguinte: segundo o livro, esse código é inválido
class ClasseTeste {
public static void main(String[] guj) {
final int a;
a = 2;
int x = 1;
switch(x){
case a:
break;
}
}
}
Na linha 07, teremos um erro de compilação, por que a variável ‘a’ deve ser constante. Se eu inicializá-la na declaração, o problema é resolvido. Dúvida: declarando como final não basta para que ela seja constante? Por que tenho que inicializar na linha que declaro? Do jeito que está no código, eu consigo imprimir a variável na saída, mas não posso usar no switch. Por quê?
Agradecido galera.
Quando você a inicializa como final o java sabe que não vai mudar ela em qualquer parte…
Quando você apenas declara ela como final e faz a primeira atribuição aleatoriamente o java nega. Porque imagine, você poderia setá-la só após o switch. (;
Hum… Faz sentido. Mas a possibilidade de setar depois do switch se parece mais com o erro de compilação “variable may not have been initialized”. Nesse caso, o erro é “constant expression required”, como se o fato de initicializar depois fizesse com que ela deixasse de ser constante. Lembrando que posso fazer a mesma coisa se não utilizar o switch, como abaixo:
class ClasseTeste {
public static void main(String[] guj) {
final int a;
a = 2;
int x = 1;
System.out.println(a);
}
}
Nesse caso, o compilador não reclama se possívelmente a variável final possa não ser inicializada.
uma constante em java utiliza os dois modificadores: static e final
abs
O modificador final faz com que a variável não possa ter seu valor alterado. ela pode apenas ser inicializada. É uma constante.
final int a = 0;
void metodo() {
a = 1; // erro
}
final int a;
void metodo() {
a = 1; // ok, inicializou
a = 2; // erro, não é permitido alterar
}
abrass
mfiuzajunior, isso acontece porque o case requer uma “constant expression”, que são valores constantes.
ex:
switch (x) {
case 1:
break;
}
o valor 1 é uma “constant expression”, que, resumidamente, são valores conhecidos antes do tempo de execução, mais detalhes em http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313
então, quando você fizer assim, vai funcionar:
class ClasseTeste {
public static void main(String[] guj) {
final int a = 2;
int x = 1;
switch(x){
case a:
break;
}
}
}
e assim não
class ClasseTeste {
public static void main(String[] guj) {
final int a;
a = 2;
int x = 1;
switch(x){
case a:
break;
}
}
}
isso só ocorre porque o compilador java, considera que cada linha é uma ação, então, se você fizer “final int a;” o compilador considera que o valor dessa variável será conhecido somente em tempo de execução,
e, no case tem que ser uma “constant expression”, ou seja, ser conhecida antes do tempo de execução.
já quando você faz “final int a = 2;” o compilador entende que esse valor não será alterado e considera essa “variável” como uma “constant expression”.
já o código abaixo funciona pois ele não requer nenhuma “constant expression”, então ele não reclama de você fazer isso.
class ClasseTeste {
public static void main(String[] guj) {
final int a;
a = 2;
int x = 1;
System.out.println(a);
}
}
Espero que tenha sido claro
abraços =P
Hum… tem uma sutileza aí que vocês não pegaram. O código que segue:
final int a; // note que você não pode usar o valor de a antes de defini-lo mais abaixo
a = 2; // agora você definiu o valor de a como 2
System.out.println (a);
usa uma sutileza do Java chamada de “blank final”.
Nesse caso, se você consegue ler especificações de linguagem (parece que você está lendo um livro de Direito Tributário, ou seja, é meio difícil de entender para os que não são entendidos, e tem algumas regras não intuitivas), pode ver o que está escrito em:
http://java.sun.com/docs/books/jls/third_edition/html/defAssign.html#53690
Excelente explicação fmachado.dev. Fiquei um pouco ausente quanto à essa questão desde meu último post e voltei a dar uma olhada agorinha, e só então, depois de ter achado a explicação, voltei ao tópico e vi q vc tinha acertado em cheio. É exatamente isso. No livro da Kathy explica, tão discretamente que me passou desapercebido na minha primeira leitura, que o case só aceita compile time constants. Pesquisando, achei a mesma explicação que vc deu: são constantes definidas em tempo de compilação. Então minhas dúvidas foram sanadas.
Agradeço a todos que responderam.
Está ai a explicação escrita no outro topico:
[quote=fmachado.dev]mfiuzajunior, isso acontece porque o case requer uma “constant expression”, que são valores constantes.
ex:
switch (x) {
case 1:
break;
}
o valor 1 é uma “constant expression”, que, resumidamente, são valores conhecidos antes do tempo de execução, mais detalhes em http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313
então, quando você fizer assim, vai funcionar:
class ClasseTeste {
public static void main(String[] guj) {
final int a = 2;
int x = 1;
switch(x){
case a:
break;
}
}
}
e assim não
class ClasseTeste {
public static void main(String[] guj) {
final int a;
a = 2;
int x = 1;
switch(x){
case a:
break;
}
}
}
isso só ocorre porque o compilador java, considera que cada linha é uma ação, então, se você fizer “final int a;” o compilador considera que o valor dessa variável será conhecido somente em tempo de execução,
e, no case tem que ser uma “constant expression”, ou seja, ser conhecida antes do tempo de execução.
já quando você faz “final int a = 2;” o compilador entende que esse valor não será alterado e considera essa “variável” como uma “constant expression”.
já o código abaixo funciona pois ele não requer nenhuma “constant expression”, então ele não reclama de você fazer isso.
class ClasseTeste {
public static void main(String[] guj) {
final int a;
a = 2;
int x = 1;
System.out.println(a);
}
}
Espero que tenha sido claro
abraços =P
[/quote]