Controle de Fluxo
Marco Antonio
Introdução
• Controle de fluxo inclui as seguintes
situações:
–
–
–
–
Declarações de if e switch
Laços com break e continue
Controle de exceções
assent
Identação
if (exam.done())
if (exam.getScore() < 0.61)
System.out.println("Try again.");
else
System.out.println("Java master!");
Teste
public class Teste {
public static void main(String[] args) {
byte x = 10;
if (x < 0) {
if (x == 11) {
System.out.println("x é igual 11");
} else if (x == x--) {
System.out.println("x é menor que 11");
}
} else
System.out.println("x não é menor que 0");
}
}
Resultado
• X não é menor que 10
Teste
public class Teste {
public static void main(String[] args) {
byte x = 10;
if (x <= x--) {
if (x == 11) {
System.out.println("x é igual 11");
} else if (x == x--) {
System.out.println("x é menor que 11");
}
} else
System.out.println("x não é menor que 0");
}
}
Resultado
• x é menor que 11
Teste
public class Teste {
public static void main(String[] args) {
byte x = 10;
if (x <= --x) {
if (x == 11) {
System.out.println("x é igual 11");
} else if (x == x--) {
System.out.println("x é menor que 11");
}
} else
System.out.println("x não é menor que 0");
}
}
Resultado
x não é menor que 0
Teste
public class Teste {
public static void main(String[] args) {
byte x = 10;
if (x < 0) if (x == 11) {
System.out.println("x é igual 11");
} else if (x == x--) {
System.out.println("x é menor que 11");
} else
System.out.println("x não é menor que 0");
}
}
Resultado
• Não imprime nada...
Teste
public class Teste {
public static void main(String[] args) {
boolean b = false;
if (b = true) { System.out.println("b é verdadeiro"); }
else { System.out.println("b é false"); }
}
}
Teste
public class Teste {
public static void main(String[] args) {
int x = 0, y = 0, a = 1, z = 3;
if (x > 3) y = 2;
z += 8;
a = y + x;
}
}
Switch
• Chaveamento de valores
Teste
public class Teste {
public static void main(String[] args) {
byte x = 3;
switch (x) {
case 1:
System.out.println("x vale 1");
break;
case 2:
System.out.println("x vale 2");
break;
default:
System.out.println("x é maior que 2");
break;
}
}
}
Resultado
• x é maior que 2
Teste
public class Teste {
public static void main(String[] args) {
byte x = 1;
switch (x) {
case 1:
System.out.println("x vale 1");
break;
case 2:
System.out.println("x vale 2");
default:
System.out.println("x é maior que 2");
break;
}
}
}
Resultado
•
•
•
•
x vale 1
Altere o x para 2.
O que acontece?
Atenção para o break.
Teste
public class Teste {
public static void main(String[] args) {
byte x = 2;
switch (x) {
case 1:
System.out.println("x vale 1");
break;
default:
System.out.println("x é maior que 2");
break;
case 2:
System.out.println("x vale 2");
}
}
}
Teste
public class Teste {
public static void main(String[] args) {
byte x = 1;
switch x {
case 1:
System.out.println("x vale 1");
break;
case 2:
System.out.println("x vale 2");
default:
System.out.println("x é maior que 2");
break;
}
}
}
Teste
int x = 10;
switch (x) {
case 1: { ... }
case 2: { ... }
case 1: { ... }
}
// Erro de compilação: duplicate case label
Teste
long x = 100;
switch (x) { // Erro de compilação: possible loss of precision
case 1: { ... }
case 2: { ... }
}
•
Mude o tipo de x para String.
Teste
final int op1 = 1;
final int op2 = 2;
int op3 = 3;
int opcao = 2;
switch (opcao) {
case op1: { ... } // ok, op1 é final
case op2: { ... } // ok, op2 é final
case op3: { ... } // Erro de compilação: constant expression required
default: { ... }
}
Teste
int x = 1;
switch (x) {
case 1: System.out.println("1");
default: System.out.println("default");
case 2: System.out.println("2");
case 3: System.out.println("3");
case 4: System.out.println("4");
}
Observações
• Não tem break, imprime tudo.
Teste
public class Teste {
public static void main(String[] args) {
int x = 3;
switch (x) {
case 1:
System.out.println("1");
default:
System.out.println("default");
case 2:
System.out.println("2");
case 3:
System.out.println("3");
case 4:
System.out.println("4");
}
}
}
Observações
• Imprime 3 e 4.
Teste
public class Teste {
public static void main(String[] args) {
final int x = 2;
for (int i = 0; i < 2; i++) {
switch (i) {
case x - 1:
System.out.print("1 ");
default:
System.out.print("def ");
case x:
System.out.print("2 ");
break;
case x + 1:
System.out.print("3 ");
}
}
}
}
Qual a solução
• a) Não será compilado
b) def 2 def 2 1
c) def 2 1 def 2
d) def 2 1 def 1
e) def 1 2 def 1
Teste
public class Teste {
public static void main(String[] args) {
//int s = 9;
for (int i = 0, s = 10; i < 10; i++) {
System.out.println("" + (s + i));
}
}
}
Teste
public class Teste {
public static void main(String[] args) {
for (int i = 0; i < 10 | (i % 2) == 0; i++) {
System.out.println("" + i);
}
}
}
Atenção
• Quando a condição for falsa o loop acaba.
Teste
public class Teste {
public static void main(String[] args) {
int x = 0;
for (int i = 0; i < 10; i++) {
x = i;
if (i == 3) break;
System.out.println("i: " + x);
}
}
}
Break
• O loop acaba depois do break.
Continue
• Altere o break para continue;
• O que acontece?
• O loop passar para o próximo i.
Teste
public class Teste {
public static void main(String[] args) {
int x,i = 0;
for (;;) {
x = i;
if (i == 3) continue;
System.out.println("i: " + x);
}
}
}
Teste
public class Teste {
public static void main(String[] args) {
for (int x = 0; (x > 5), (y < 2); x++) { }
}
}
Regra
• O que devemos lembrar é que não podemos
ter duas expressões de teste.
Rótulos
public class Teste {
public static void main(String[] args) {
for (int i = 10; i < 20; i++) {
aqui: for (int j = 1; j < 2; j++) {
if (i % 2 == 0) continue aqui; //Números pares
System.out.println(i);
}
}
}
}
Exceções
• O tratamento de exceções (não de erros) em
java é bastante completo, permitindo um
bom refinamento da aplicação.
Try/catch block
try {
// primeira linha vigiada
}
catch (Exception e) {
// primeira linha que será executada caso haja um exceção do tipo Exception
}
finally {
// bloco que será executado, havendo ou não uma exceção (sempre!)
}
Formas
try {
}
catch (MyException e) {
}
•
?
Formas
try {
}
• ?
Formas
try {
}
finally {
}
• ?
Erros
import java.io.*;
public class Erros {
public static void main(String[] args) {
metodoDoMal();
}
public static void metodoDoMal() {
try {
throw new IOException("eu fiz um erro");
} catch (IOException e) {
// código que solucionará o problema
}
}
}
Erros
package tjdf.sistj.assuntodaclassificacao.negocio;
import java.io.*;
public class Erros {
public static void main(String[] args) {
metodoDoMal(); //Qual o problema?
}
public static void metodoDoMal() throws IOException {
throw new IOException("eu fiz um erro");
}
}
Erros
import java.io.*;
import java.awt.print.*;
public class Teste {
public static void main(String[] args) {
try {
metodoDoMal();
} catch (IOException e) {
} catch (PrinterException p) {
}
}
static void metodoDoMal() throws IOException, PrinterException {
metodoPiorAinda();
}
static void metodoPiorAinda() throws PrinterException {
}
}
//Tudo certo
Erros
import java.io.*;
import java.awt.print.*;
public class Teste {
public static void main(String[] args) {
try {
metodoDoMal();
} catch (IOException e) {
}
}
static void metodoDoMal() throws IOException {
metodoPiorAinda(); //Aqui temos um problema...
}
static void metodoPiorAinda() throws PrinterException {
}
}
RealData
import java.io.*;
public class ReadData {
public static void main(String args[]) {
try {
RandomAccessFile raf = new RandomAccessFile("myfile.txt", "r");
byte b[] = new byte[1000];
raf.readFully(b, 0, 1000);
} catch (IOException e) {
System.err.println("IO Error");
System.err.println(e.toString());
e.printStackTrace();
} catch (FileNotFoundException e) {
System.err.println("File not found");
System.err.println(e.getMessage());
e.printStackTrace();
}
}
}
Hierarquia de classes
• A sequência deve ser sempre da exceção
mais especifica para a mais genérica, ou
seja: a mais específica é
FileNotFoundException, e a mais genérica é
IOException.
Principais exceções
• ArrayIndexOutOfBoundsException,
ClassCastException, NullPointerException,
ExceptionInitializerError, StackOverflowError,
NoClassDefFoundError.
• IllegalArgumentException,
IllegalStateException,
NumberFormatException, AssertionError.
Assertivas
• Use assertiva para validar argumentos em métodos privados
– Como a visibilidade é privada, você consegue detectar erros.
• Use assertiva sem condição em um bloco que presuma que
nunca seja alcançado.
– Se você tem um bloco que nunca seria alcançado, você pode
usar uma assert false, pois assim saberia se em algum
momento esse bloco está sendo alcançado.
• Lançar um AssertionError explicitamente
• Se um bloco switch não tiver uma instrução default, adicionar
uma assertiva é considerado uma boa prática
Formas
Default
assert ( i < 0 );
Simples
assert ( i > 0 ) : "Valor do i é "+i;
assert(x == 1) : aReturn();
Erros comuns
• assert(x == 1) : ;
• assert(x == 1) : metodoSemReturn();
• assert(x == 1) : ValidAssert va;
Como não usar
• Nunca manipula um AssertionError
– Não use um catch e manipula um erro de assertiva
• Não use assertiva para validar argumentos em métodos
públicos
– Você não pode garantir nada em métodos público, portanto
usar assertiva nesse caso, não é uma boa prática
• Não use assertiva para validar argumento da linha de
comando
– Isso é uma particularidade de um método público, mas segue
a mesma regra
• Não use assertivas que possam causar efeitos colaterais
– Você não pode garantia que as assertivas sempre serão
executadas, portanto o seu programa deve executar
independentemente das assertivas, e nunca de forma
diferente simplesmente porque as assertivas foram ativadas.
Como habilitar
•
•
•
•
java –ea / java -enableassertion // habilita assertion
java -da / java -disableassertion // desabilita assertion
java -ea:br.com.Atimo // habilita para o pacoto br.com.Atimo
java -ea -das // habilita assertion em âmbito geral e desabilita
nas classes do systema
• java -esa // habilita nas classes do sistema
Download

CertificacaoII