controle de fluxo, exceções, assertivas

42
Grupo de Estudos - SCJP Controle de Fluxo Exceções Assertivas Eduardo Silva ufpb, junho de 2009

Upload: elenilson-vieira

Post on 18-Nov-2014

3.120 views

Category:

Technology


1 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Controle de Fluxo, Exceções, Assertivas

Grupo de Estudos - SCJP

Controle de Fluxo

Exceções

Assertivas

Eduardo Silva

ufpb, junho de 2009

Page 2: Controle de Fluxo, Exceções, Assertivas

instruções ifFormato básico:

if (expressãoBooleana) {

...println(“entrou no if”);

}

if (new Boolean(true) && !ehMentira()) {

...println("no if");

}

if (a == b & b > c || c != d && d <= a) {

...println("dentro");

}

Page 3: Controle de Fluxo, Exceções, Assertivas

else e else-ifif (nota > 7) {

...println(“maior”);

} else {

...println(“não-maior”);

}

if (peso < 40) {

...println(“vôou”);

} else if (peso < 55) {

...println(“magro”);

} else if (peso < 65) {

...println(“quase”);

} else {

...println(“beleza”);

}

if true {

...println(“it's true”);

}

if (a < b) {

...println("um");

}

if (c > b) {

...println("dois");

} else {

...println("tres");

} else if (true) {

...println("quatro");

}

Page 4: Controle de Fluxo, Exceções, Assertivas

avisosif (ehVerdade())

if (!ehVerdade())

...println(“paradoxo”);

else

...println(“pior que é verdade”);

int verum = 1, falsum = 0;

// inválidos:

if (verum)

if (verum == true)

if (1)

if (falsum == false)

// válidos:

if (verum == 1)

if (falsum == 0)

� casado com o último if

if (nota > 7)

...println(“passou”);

...println(“deu beleza”);

Page 5: Controle de Fluxo, Exceções, Assertivas

instrução switchchar ch = 'a';

if (ch == 'c') {

...println(“cê”);

} else {

if (ch == 'b') {

...println(“bê”);

} else {

if (ch == 'a') {

...println(“á”);

} else {

...println(“outra”);

}

}

}

char ch = 'a';

switch (ch) {

case 'c':

...println(“cê”);

break;

case 'b':

...println(“bê”);

break;

case 'b':

...println(“á”);

break;

default:

...println(“outra”);

}

Page 6: Controle de Fluxo, Exceções, Assertivas

+ switchlong l = 11;

switch (l) { }

� a expressão do switch só avaliará enums e (valores e

variáveis que puderem ser implicitamente convertidos num int)

final int x = 0, a = 1, b;

b = 2;

switch (x) {

case a:

case b:

}

� o argumento do case tem que ser uma constante em tempo

de compilação (variável literal ou final, expressão constante,

incluindo enum)

Page 7: Controle de Fluxo, Exceções, Assertivas

+ switchlong l = 11;

switch (l) { } // possible lost of precision

� a expressão do switch só avaliará enums e (valores e

variáveis que puderem ser implicitamente convertidos num int)

final int x = 0, a = 1, b;

b = 2;

switch (x) {

case a:

case b: // constant expression required

}

� o argumento do case tem que ser uma constante em tempo

de compilação (variável literal ou final, expressão constante,

incluindo enum)

Page 8: Controle de Fluxo, Exceções, Assertivas

três erros de compilação:byte b = 22;

switch (b) {

case 22:

case (b < 23):

break;

case 128:

break;

case 22:

}

Page 9: Controle de Fluxo, Exceções, Assertivas

alguns detalhesbyte b = 22;

switch (b) {

case (b < 23): // imcompatible types

...println(“switch só testa igualdade”);

break;

case 128: // possible lost of precision

...println(“o compilador sabe que 128 não cabe num byte”);

break;

case 22: // o break é opcional

case 22: // duplicate case label

...println(“mesmo valor para dois cases”);

}

Page 10: Controle de Fluxo, Exceções, Assertivas

mais algunsswitch (new Integer(127)) {

case 127 { // faltou o “:”

...println(“deu beleza?”);

}

}

int x = getNumPositivoMenorQueDez();

switch (x) {

case 2:

case 4:

case 6:

case 8:

...println(“é par”); break;

default:

...println(“é ímpar”); break;

} // passagem completa

Page 11: Controle de Fluxo, Exceções, Assertivas

imprime o que?short s = 12;

// --s;

switch (s) {

case 11: ...print(“11”);

default: ...print(“default”);

case 13: ...print(“13”);

}

Page 12: Controle de Fluxo, Exceções, Assertivas

switch-case-defaultshort s = 12;

// --s;

switch (s) {

case 11: ...print(“11”);

default: ...print(“default”);

case 13: ...print(“13”);

}

� imprime “default13”

� descomentando a segunda linha do exemplo anterior, seria

impresso “11default13”

� Ou seja, a instrução default pode não vir no final da instrução

switch e funciona como qualquer instrução case na passagem

completa

Page 13: Controle de Fluxo, Exceções, Assertivas

while e do-while� while útil quando não se sabe quantas vezes o bloco terá que

ser repetido

while (expressaoBooleana) {

// um mói de coisa

}

� do-while útil quando se quer executar um bloco ao menos

uma vez antes de avaliar a expressão

do {

// outro mói

} while (outraExpressao); // <- detalhe no ponto-e-vírgula

Page 14: Controle de Fluxo, Exceções, Assertivas

for� útil quando se souber o números de vezes que executará as

instruções do bloco do loop

for (/* inicialização */ ; /* condição */ ; /* iteração */) {

// corpo do loop

}

for (int k = 0, j = 1; k < 10 && j < 10; k++, --j) {}

// beleza

}

...println(k); // k já não existe mais aqui

...println(j); // cannot find symbol

� ecxeto por uma saída forçada, as expressões de iteração e

condição serão as últimas a seres executada num loop for

Page 15: Controle de Fluxo, Exceções, Assertivas

saídas forçadas e +�break salto para a 1ª instrução depois do loop

�return retornará imediatamente ao método chamador

�System.exit() o programa será interrompido, VM será

encerrada

int i = 0;

for(;i<10;) {

++i;

// mais coisas aqui

} // equivalente a um while

for (;;) { ... } // loop infinito

for (; false; ) { ... } // unreachable statement

for (int a = 1, b = 3; b != 1; System.out.println(b)) { // válido!

b -= a;

}

Page 16: Controle de Fluxo, Exceções, Assertivas

for aprimorado (for-each)for (declaração : expressão)

int x;

long x2;

Long[] La = {4L, 5l, 6l};

long[] la = {7l, 8L, 9};int[][] dobrado = {{3, 2, 1}, {6, 5, 4}};

String[] ss = {“um”, “dois”, “quatro”};

Animal[] animais = {new Dog(), new

Cat()};

for (float y: la); // ??

for (long lp: La);

for (int[] n: dobrado);

for (int n2: dobrado[1]);

for (String s: ss);

for (Object o: ss);

for(Animal a: animais);

for(x2: la);

for(int x2: dobrado);

for(int x3: la);

for(Dog d: animais);

Page 17: Controle de Fluxo, Exceções, Assertivas

continue e break�continue próxima iteração do laço (não pode vir fora um loop)

�break vai para próxima linha depois do laço

for (int in = 0; i < 10; i++) {

continue; // loop infinito?

}

for (int i = 0; i < 10; i++) {

if (i & 1 == 0) {

continue;

}

if (i == 8) {

break;

}

...println(i);

}

Page 18: Controle de Fluxo, Exceções, Assertivas

instruções rotuladas� muitas instruções em java podem ser rotuladas, mas isso é

mais comum em loops

� úteis em loops aninhados

� o rótulo precisa estar de acordo com as regras de nomes de

variáveis válidos

rotulo1:

for (int i = 0; i < 10; i++) {

for (int j = 0; j < 10; j++) {

...println(j);

continue rotulo1;

}

...println(“ufa”);

}

...println(“fim”);

Page 19: Controle de Fluxo, Exceções, Assertivas

+ rótulos� as instruções continue e break rotuladas devem ficar dentro

do loop que tiver o mesmo rótulo ou o código não será

compilado

int b = 10;

int[] a = new int[4];

1rotulo:

for (int n: a) break 1rotulo;

rotulo2: {

while (b > 0) {

...println(b--);

}

continue rotulo2;

}

Page 20: Controle de Fluxo, Exceções, Assertivas

manipulação de exceções� produz código eficiente e organizado

� mantém código de exceções separado do código “principal'

� permite “reutilização” do código de exceção para as diferentes

exceções possíveis

� exceção significa “condição excepcional” (falha no hardware,

exaustão de recursos, erros...)

� quando um evento excepcional ocorre, diz-se que uma

exceção será lançada

� o código responsável por fazer algo com a exceção é

chamado de manipulador de exceções

Page 21: Controle de Fluxo, Exceções, Assertivas

try catch� try indica um bloco de código em que poderá ocorrer uma

exceção (região protegida)

� a cláusula catch associa uma (ou mais) exceção(ões) a um

bloco de código que a manipulará

� se existirem blocos catch, então eles devem ficar sempre

depois do bloco try e nada pode ficar entre eles

try {

captureArquivoNaRede();

leiaArquivoePreenchaTabela();

}

catch (NaoPodeCapturarArquivoNaRede e) {

useArquivoLocal();

}

Page 22: Controle de Fluxo, Exceções, Assertivas

finally� o bloco finally será sempre executado, mesmo que nenhuma

exceção seja lançada

� útil para “executar limpeza “ (fechar arquivos, liberar sockets

de rede, etc)

void fazAlgo() {

try {

int a = 10;

a /= 0;

} catch (ArithmeticException e) {

System.out.println("no catch");

return;

} finally {

System.out.println("no finally");

}

} // o que será impresso?

try {

int a = 10 / 0;

}

System.out.println(a);

try {

int b = 10 / 0;

} finally {

...println(“finally”);

} catch (Exception e) {

...println(“catch”);

}System.out.println(b);

Page 23: Controle de Fluxo, Exceções, Assertivas

propagação de exceçõesclass Pilha {

public static void main(String[] args) {

new Cap5().facaUm();

}

void facaUm() {

facaDois();

}

void facaDois() {

int a = 1/0;

}

}

Exception in thread "main" java.lang.ArithmeticException: / by zero

at Cap5.facaDois(Cap5.java:11)

at Cap5.facaUm(Cap5.java:8)

at Cap5.main(Cap5.java:5)

fazDois()

fazUm()

main()

Page 24: Controle de Fluxo, Exceções, Assertivas

hierarquia de exceções� as exceções são sempre subclasses de java.lang.Exception

� há duas subclasses que derivam de Throwable: Exception e Error

� os aplicativos geralmente não conseguem se recuperar de um erro,

então mesmo que seu código não os manipule, ele ainda será compilado

� a classe Throwable fornece o método printStackTrace() para exibir o

rastreamento de pilha do local onde a exceção ocorreu

� os tipos RunTimeException, Exception, Error e Throwable podem ser

lançados com o uso da palavra throw e podem ser capturados (embora

raramente seja capturado algo que não seja um subtipo de Exception)

Error

Object Throwable

Exception RunTimeException

Page 25: Controle de Fluxo, Exceções, Assertivas

correspondência de exceções� os manipuladores de exceções mais específicos devem

sempre ser inseridos acima dos de exceções gerais

� se uma classe Exception não for o subtipo ou supertipo da

outra, a ordem na qual as cláusulas catch serão inseridas não

importará

try {

RandomAccessFile raf = new RandomAccessFile("myfile.txt", "r");

byte[] b = new byte[1000];

raf.readFully(b, 0, 1000);

} catch (FileNotFoundException e) {

System.out.println("file not found");

} catch (IOException e) {

System.out.println("IO Error");}

Page 26: Controle de Fluxo, Exceções, Assertivas

declarando exceções� uma exceção é dita “verificada” se não é do tipo

RunTimeException

� as exceções verificadas que um método pode lançar devem

ser declaradas, mesmo que ele lance de maneira indireta

� utiliza-se a palavra-chave throws na assinatura do método

para declarar que o método lança uma dada exceção

� quando um método declara que lança uma exceção, não

significa que ele sempre o fará, mas sim que ele pode fazê-lo

void doStuff() { doMore(); }

void doMore() {

throw new IOException();

} // dois erros aqui

Page 27: Controle de Fluxo, Exceções, Assertivas

+ exceçõespublic static void main(String[] args) {

try {

new Cap5().fazUm();

} catch (IOException e) {}

// IOException is never thrown in body

// of corresponding try statement

}

void fazUm() { fazDois(); }

void fazDois() {

try {

throw new IOException();

} catch (IOException rte) {

rte.printStackTrace();

}

}

Page 28: Controle de Fluxo, Exceções, Assertivas

ainda + exceçõespublic static void main(String[] args) {

new Cap5().fazUm();

}

void fazUm() {

try {

throw new Error();

} catch (Error e) {

throw e;

}

} void fazUm() {

try {

throw new IOException();

} catch (IOException e) {

throw e;

}

Page 29: Controle de Fluxo, Exceções, Assertivas

exceções e erros lançados pelo

JVM� NullPointerException

class NPE {

static String s;

public static void main(String[] args) {

System.out.println(s.length());

}

}

� StackOverflowError

void recursivo() {

recursivo()

}

Page 30: Controle de Fluxo, Exceções, Assertivas

exceções & erros lançados

programaticamente� “programaticamente” = criado por um aplicativo e/ou por um

desenvolvedor de API

// uma possível implementação do parseInt() de Integer:

int parseInt(String s) throws NumberFormatException {

boolean parseSuccess = false;

int resulta = 0;

// parsing complicado aqui

if (!parseSuccess) {

throw new NumberFormatException();

}

return result;

}

� AssertionError também é lançado programaticamente

Page 31: Controle de Fluxo, Exceções, Assertivas

Os dez erros e exceções principais� ArrayIndexOfBoundsException: lançada ao se tentar acessar um

array com um valor de índice inválido

int[] a = new int[10];

a[a.length] = 0;

� ClassCastException: lançada ao se tentar converter uma

variável de referência em um tipo que não passa no teste é-um

Object o = new Integer(0);

System.out.println((String)o);

� IllegalArgumentException: lançada quando um método

recebe um argumento formatado de forma diferente do que o

método espera

- lançado programaticamente

Page 32: Controle de Fluxo, Exceções, Assertivas

Os dez erros e exceções principais� IllegalStateException: quando o estado do ambiente não bate com a

operação sendo tentada, p.ex., usando-se um Scanner que já foi fechado.

- lançada programaticamente

� NullPointerException

- lançada pela JVM

� NumberFormatException: lançada quando um método que

converte uma String em um número recebe uma String que não

consegue converter.

- lançada programaticamente

String s = "123deoliveira4";

int i = Integer.parseInt(s);

� AssertionError: daqui a pouco

- lançada programaticamente

Page 33: Controle de Fluxo, Exceções, Assertivas

Os dez erros e exceções principais� ExceptionInInitializerError: ao se tentar inicializar uma variável

estática de um bloco de inicialização.

- lançada pelo JVM

class Cap5 {

static int a;

static {a = 2/0;}

}

� StackOverflowError

- lançada pelo JVM

� NoClassDefFoundError: quando o JVM não consegue

encontrar uma classe de que precisa, por causa de um erro de

linha de comando, uma questão referente ao classpath ou um

arquivo .class que esteja faltando.

$java ClasseX.class

Page 34: Controle de Fluxo, Exceções, Assertivas

assertivas� pertime que se teste suas suposições durante o desenvolvimento, sem

o desgaste (de tempo e sobrecarga do programa) de escrever

manipuladores para exceções que se supõe que nunca ocorrerão

void tam(int num) {

assert (num >= 0);

// código útil aqui

}

// ao invés de

void tam(int num) {

if (num >= 0) {// código útil aqui

}

else {

...println(“o número é negativo”);

}

}

Page 35: Controle de Fluxo, Exceções, Assertivas

duas versões de assert� Muito simples: assert (y > x);

� Simples: assert (num >= 0): "tá com mopa"

Exception in thread "main" java.lang.AssertionError: tá com mopa

at Cap5.tam(Cap5.java:11)

at Cap5.fazAlgo(Cap5.java:8)

at Cap5.main(Cap5.java:5)

� normalmente as assertivas são ativadas quando um aplicativo está

sendo testado e deuprado, porém, são desativadas quando ele é

distribuido

� quando a palavra “expressão” for citada em alguma questão, suponha

que ela está se referindo à primeira expressão de um assert (a expressão

booleana)

Page 36: Controle de Fluxo, Exceções, Assertivas

regras das expressões de assertivasvoid semRetorno() {}

int retornaInt() { return 0; }

void vai() {

int x = 1;

boolean b = true;

assert(x==1);

assert(x = 1);

assert(b);

assert(x);

assert true;

assert 0;

assert(x == 1): x;assert(x == 1): ;

assert(x ==1): retornaInt();

assert(x == 1): semRetorno();

assert(x == 1): new ValidAssert();

assert(x == 1): ClasseB b;

}

Page 37: Controle de Fluxo, Exceções, Assertivas

ativando assertivas� as assertivas foram adicionadas na versão 1.4 e “assert” se tornou

uma palavra-chave, logo você deve utilizar “assert” como identificador ou

como palavra-chave, mas não ambos

� o compilador Java 5 usará a palavra-chave assert por padrão, a não

ser você o instrua do contrário

char assert = 'a';

$ javac Cap5.java // Error

$ javac -source 1.3 Cap5.java // Warning

assert(a > 0);

$ javac -source 5 Cap5.java // Beleza

$ javac -source 1.3 Cap5.java // Error

Page 38: Controle de Fluxo, Exceções, Assertivas

execução de assertivas� as assertivas vêm desativadas por padrão

� ativando assertivas:

$ java -ea pacote.subpacote.Classe

$ java -enableassertions pacote.subpacote.Classe

� desativando assertivas

$ java -da pacote.subpacote.Classe

$ java -disableassertions pacote.subpacote.Classe

� ativação e desativação seletiva:

$ java -ea:com.foo.Bar$ java -ea:com.foo...

$ java -ea -dsa � desativando nas classes do sistema

$ java -ea -da:com.foo...

Page 39: Controle de Fluxo, Exceções, Assertivas

uso apropriado� “apropriado” = “correto”

� nunca se deve manipular uma falha de assertiva (apesar de ser

possível)

� o erro AssertionError não concede acesso ao objeto que o gerou (??)try {

assert (num >= 0): "deu mopa";

} catch (AssertionError ae) {

ae.printStackTrace();

} // uso inapropriado

� não use assertivas para validar argumentos de um método public: é

preciso garantir que nenhuma restrição a argumentos seja imposta

public void facaAlgo(int x) {

assert (x > 0);

// código que mexe com x

} // melhor seria lançar uma IllegalArgumentException

Page 40: Controle de Fluxo, Exceções, Assertivas

+ uso apropriado� use assertivas para validar argumentos de um método privado (pois

provavelmente você controlará todos os métodos que o chamarão)

private fazAlgo(byte x) {

assert(x > 0);

}

� não use assertivas para validar argumentos de linha de comando (se

precisar fazer isso, use o mecanismo de exceções)

� use assertivas, mesmo em métodos públic, para procurar instruções

case que sabe que nunca ocorrerãoswitch(x) {

case 1: fazUm();

case 2: fazDois();

case 3: fazTres();

default: assert false;

}

Page 41: Controle de Fluxo, Exceções, Assertivas

++ uso apropriado� não use assertivas que posdem causar efeitos colaterais

public void fazAlgo() {

assert(modificaAlgo());

// continua...

}

boolean modificaAlgo() {

x++ = y; // outro erro aqui

return true;

}

� uma assertiva deve deixar o programa no mesmo estado em que estava antes da expressão, pois não há garantia de que as expressões

assertivas sejam sempre executadas

Page 42: Controle de Fluxo, Exceções, Assertivas

fim