Questao de Labeled Statement

17 respostas
F

Olá pessoal!

void crazyLoop() 
{
    int c = 0;
    JACK: while (c < 8) 
    {
        JILL: System.out.println(c);
        if (c > 3) break JACK; else c++;
    }
}

a. It’ll not compile.

b. It’ll throw an exception at runtime.

c. It’ll print numbers from 0 to 8

d. It’ll print numbers from 0 to 3

e. It’ll print numbers from 0 to 4

17 Respostas

J

Acho eu que a letra d.

S

Não tenho certeza, mas o código após um label não tem que ser um loop?

Acho que letra A.

Se compila, então seria a E, já que o print vem antes do break.

F

Tem certeza??

Eu marquei “a”, mas na verdade não é nem “a” e nem "d"
Eu tinha pensado que quando rotula alguma lugar que não esteja
antes de uma instrução de loop, o compilador reclamava…

Mas veja bem, não é assim, você pode sair rotulando tudo o que vc
quiser no seu programa… porém só poderá usar “break ou continue
rotulado” naqueles rótulos que estiverem necessariamente logo antes
da statement de loop.

Então sabendo disso, ele vai compilar normal , porque o label “JILL”,
apesar de estar colocado em um locar inapropriado, ele nunca e´usado
com break ou continue rotulados…

Fazendo o fluxo do programa, imprime
0
1
2
3
4
e já que 4 é maior que 3 , entra no if e sai do loop onde jack aponta…

S

Se tentar usar break JILL; ?
Erro de compilação?

R

Gostaria de complementar:

Nos blocos rotulados, como o do código abaixo, o rótulo não precisa estar imediatamente antes de um loop. No entanto os blocos rotulados somente podem ser usados com break.

package teste;

public class main  { 
  public static void main(String[] args) { 
    int x = 2;
    
    stop: {
      System.out.println(x);
      
      for (int i = 0; i < 10; i++) {
        System.out.println(i);
        
        if (i > 3)
          break stop;
      }
    }
  }  
}
J

fmartins escreveu:

agora tenho !!!, na verdade marquei a letra ‘D’ pois não me liguei que antes do if vinha:
JILL: System.out.println©;

S

Olha só o que acontece se trocar JACK por JILL:

R

Schuenemann,

Se você trocar break JACK por break JILL o compilador vai reclamar porque o rótulo não é a última linha de comando antes de um loop. Você pode resolver este problema delimitando um bloco para JILL com {}. Aí o compilador não vai reclamar.

OBS: O que falei não vale para “continue”!!! :wink:

S

“Robson”:
Schuenemann,

Se você trocar break JACK por break JILL o compilador vai reclamar porque o rótulo não é a última linha de comando antes de um loop. Você pode resolver este problema delimitando um bloco para JILL com {}. Aí o compilador não vai reclamar.

OBS: O que falei não vale para “continue”!!! :wink:

Acho que não é bem assim.
Isso só compilará se o break estiver dentro desse bloco do label, e esse bloco tem que ser uma repetição ou switch.
No caso do continue seria o mesmo, com excessão que precisa estar numa repetição.

Acertei?

F

MEUS DEUSES 8O

eu jurava q sabia isso, marcaria a letra A e sairia morto de feliz!!

o q vcs acham de publicarmos aqui as regrinhas bem direitim, vou tentar pelo q entendi:

  1. Um label pode está em qualquer parte do código, se nunca for chamado via continue ou break. (entaum pra q serve? será q o goto chama? é assim no basic).

  2. Um label chamado por um break pode: ou está rotulando um bloco cujo break de chamada está dentro ou vim logo antes de algum laço (for,while,do)

  3. Um label chamado por um continue deve vim logo antes de um laço e pronto!!

esqueci ou errei alguma regra?

R

Fábio,

O goto e const, são palavras reservadas da liguagem mas não podem ser usadas. O compilador reclamará se houver uma tentativa de uso.

Quanto as regras, as minhas são:
1 - break faz a execução saltar para a primeira linha de comando após o loop onde foi chamado

2 - continue faz a execuçao saltar para o início do loop onde foi chamado. Se o continue estiver dentro de um comando for, a variável de controle será incrementada

3 - break e continue devem ser o última linha de comando no “bloco” onde forem chamados

4 - o label “sem” chaves que for referenciado por um break deve ser a última linha de comando antes do “bloco” externo

5 - o label “sem” chaves que for referenciado por um continue deve ser a última linha de comando antes do “loop” externo

6 - o label “com” chaves que for referenciado por um break constitui o próprio “bloco” externo

7 - label “com” chaves não pode ser referenciado por continue :oops:

F

lembrando que:
1 A nomenclatura de um label (rótulo) segue as normas de nomes para variaveis, ou métodos ou classes.
2 Ela pode vir antes de uma instrução que pode ser

Statement:
	StatementWithoutTrailingSubstatement
	LabeledStatement
	IfThenStatement
	IfThenElseStatement
	WhileStatement
	ForStatement

StatementWithoutTrailingSubstatement:
	Block
	EmptyStatement
	ExpressionStatement
	SwitchStatement
	DoStatement
	BreakStatement
	ContinueStatement
	ReturnStatement
	SynchronizedStatement
	ThrowStatement
	TryStatement

StatementNoShortIf:
	StatementWithoutTrailingSubstatement
	LabeledStatementNoShortIf
	IfThenElseStatementNoShortIf
	WhileStatementNoShortIf
	ForStatementNoShortIf

Ou seja, Um Label pode ser colocado antes um outro label
Ex.:

Label1: Label3: Label4: Label5: ......

Antes de if,while, for, bloco, instrução vazia(:wink: , expressão, do…while, break, continue, return,throw,try, synchronized(blocos no caso)

label: synchronized(object){
             //Código bloqueado
       };

3 Não existe restrição a repetição de nomes declarados como label
Você pode ter isso no seu código

hsjs: System.out.println("/");
    hsjs: System.out.println("/");
    hsjs: System.out.println("/");
    hsjs: for(;;){
      break hsjs;
    }

4 o break poderá ou não chamar o label, caso chame é virá antes do label terminando com ( ; ) break Identifieropt ;

5 o break deverá estar dentro de um loop switch, while, do, or for, ou um bloco rotulado. E fará com que com haja um interrupção do bloco que ele se refere,que poderá ser o label que ele se refere ou ao loop mais interno.

6 o break deverá ser a última instrução dentro do seu bloco.
Senão por exemplo:

label:{
      break label;
      System.out.println("saindo do bloco");
    }

O compilador reclama “Error: statement not reachable”

7 caso o break esteja dentro de um catch, e houver o bloco
finally, antes de sair do bloco abruptalmente, o finally e´ executado!

label:{
      try{
        throw new Exception();
      }catch(Exception e){
        break label;
      }finally{
        System.out.println("finally");
      }      
    }

8 o continue poderá ou não chamar o label, caso chame é virá antes do label terminando com ( ; ) continue Identifieropt ;

9 difere do break, porque o continue só pode ser usado dentro de um loop, e caso use algum rótulo, o mesmo deve estar antes de um loop.

F

legal, vou organizar e imprimir isso aqui :cool:

F

:sad:

pensando eu q sabia tudo de break e continue

tenteni inventar um loop sem o uso de for e while, assim:

class Teste {

public static void main(String args[]) {

int i = 0;
loop: {
  System.out.println(i);
  i++; 
  if (i < 10) break loop; 
}

}

}

:?: pq num rola?

S

pensando eu q sabia tudo de break e continue

tenteni inventar um loop sem o uso de for e while, assim:

class Teste {

public static void main(String args[]) {

int i = 0;
loop: {
  System.out.println(i);
  i++; 
  if (i < 10) break loop; 
}

}

}

:?: pq num rola?[/quote]

break só pode ser usado dentro de loops ou switch.
continue, somente dentro de loops.

No seu exemplo não tem nenhum loop, só um label que por “coincidência” tem o nome “loop”.
Como nem break, nem continue podem ser chamados, esse label é inútil :slight_smile:

F

“Schuenemann”:
“fabiostb”:
:sad:

pensando eu q sabia tudo de break e continue

tenteni inventar um loop sem o uso de for e while, assim:

class Teste {

public static void main(String args[]) {

int i = 0;
loop: {
  System.out.println(i);
  i++; 
  if (i < 10) break loop; 
}

}

}

:?: pq num rola?

break só pode ser usado dentro de loops ou switch.
continue, somente dentro de loops.

No seu exemplo não tem nenhum loop, só um label que por “coincidência” tem o nome “loop”.
Como nem break, nem continue podem ser chamados, esse label é inútil :)

O que você fez nesse exemplo está perfeitamente aceito no Java,
agora não quer dizer que seja um loop.
O que você fez foi:

Rotular um bloco com um nome "loop"
e caso o i for menor que 10, vai ser logo de ínicio, então ele sai
desse bloco!!!
Observe:

loop:  {
            System.out.println(i);
            i++;

            if (i > 10) {
                break loop;
            }
            System.out.println("Se passou por aqui ... entao nao entrou no if de cima");
        }
i é menor que 10? sim , i = 1, menor q 10.

Ele vai entrar dentro do if  e vai sair do bloco rotulado com label;

e seguir o programaColoquei um Saida no console pra verificar se ele chega  mas

nesse seu exemplo  ele vai ignorar o System.out.println("…")

e tudo que houver depois  e que estiver dentro do bloco.

Não confunda break rotulado com goto…

F

blz fmartins, entendi!

pensei que a expressao “break rótulo” transfereria o fluxo para o local do break e executaria o bloco loop do começo, dai seria um loop perfeito :oops:

Criado 9 de março de 2005
Ultima resposta 15 de mar. de 2005
Respostas 17
Participantes 5