59
SCJP 6 Clase 5 – Control de Flujo, Exceptions y Assertions Ezequiel Aranda Sun Microsystems Campus Ambassador

Clase5 controldeflujo

Embed Size (px)

Citation preview

Page 1: Clase5 controldeflujo

SCJP 6 Clase 5 – Control de Flujo,

Exceptions y Assertions

Ezequiel Aranda

Sun Microsystems Campus Ambassador

Page 2: Clase5 controldeflujo

Disclaimer & Acknowledgments

>!Even though Ezequiel Aranda is a full-time employee of Sun Microsystems, the contents here are created as his own personal endeavor and thus does not reflect any official stance of Sun Microsystems.

>!Sun Microsystems is not responsible for any inaccuracies in the contents.

>!Acknowledgments – The slides of this presentation are made from “SCJP Unit 5” by Warit Wanwithu and Thanisa

Kruawaisayawan and SCJP Workshop by P. Srikanth.

>!This slides are Licensed under a Creative Commons

Attribution – Noncommercial – Share Alike 3.0

>!http://creativecommons.org/licenses/by-nc-sa/3.0/

Page 3: Clase5 controldeflujo

AGENDA

>!if

>!for

>!for “mejorado”

>!break y continue

>!excepciones

>!assertions

Page 4: Clase5 controldeflujo

if

>!Observen este ejemplo:

if (exam.done())

if (exam.getScore() < 0.61)

System.out.println("Try again.");

// ¿A que “if” pertenece el próximo else?

else

System.out.println("Javamaster!");

>!El “else” pertenece al segundo “if”

Page 5: Clase5 controldeflujo

if (II)

int trueInt = 1;

int falseInt = 0;

if (trueInt) // ilegal

if (trueInt == true) // ilegal

if (1) // illegal

if (falseInt == false) // ilegal

if (trueInt == 1) // legal

if (falseInt == 0) // legal

>!La única expresión legal en un if es una de tipo boolean.

>!En algunos lenguajes, 0 == false y 1 == true. No es así en Java.

Page 6: Clase5 controldeflujo

Switch

>!Una expresión en un switch debe evaluar a un char, byte, short, int o, a partir de Java 5, un enum.

>!Una constante en un case debe evaluar al mismo tipo que la expresión puede usar.

>!Switch solo chequea igualdad.

>!Puede colocarse el caso por defecto arriba.

Page 7: Clase5 controldeflujo

Switch (II)

>!Una vez que se encuentra una correspondencia entre las constantes del case, la JVM ejecutará el bloque de código asociado, y TODOS los bloques subsecuentes (salvo que encuentre un break en el camino). public static void main(String [] args) {

int x = 10; switch(x) {

case 5: System.out.print("five ");

case 10: System.out.print("ten ");

case 15: System.out.print("fifteen");

default: System.out.println("done");

}}

Page 8: Clase5 controldeflujo

While

>!Cualquier variable a ser utilizada en la expresión del bucle while debe ser declarada antes de la evaluación de la expresión.

while (int x = 2) { } // no legal

>!El punto clave a recordar del while es que podría no ejecutarse nunca.

Page 9: Clase5 controldeflujo

Bucles

>!Ejemplos de salidas forzadas de los bucles son:

break

return

System.exit()

exception

>!Los cuales causan que un loop termine abruptamente, sin ejecutar la expresión de la iteración.

Page 10: Clase5 controldeflujo

For

>!Las variables declaradas en la sentencia “for” son locales al bucle, y no pueden ser usadas fuera del ámbito del bucle. int i = 0;

for (;i<10;) {

i++;

}

for (int i = 0,j = 0; (i<10) && (j<10); i

++, j++) {

System.out.println("i is " + i + " j is "

+j);

}

Page 11: Clase5 controldeflujo

For (II)

>!El último detalle a destacar sobre el “for” es que las tres secciones del bucle son independientes entre si.

int b = 3;

for(int a=1; b=1;

System.out.println("iterate")){

b = b -a;

}

Page 12: Clase5 controldeflujo

For “mejorado”

>!El nuevo for incluido en Java 5 es una forma especializada del bucle que simplifica la tarea de recorrer arrays o collections.

>!En vez de tener tres componentes, tiene solo dos.

int[] a = {1,2,3,4};

for(int n : a)

System.out.print(n);

Page 13: Clase5 controldeflujo

For “mejorado” (II)

>!El viejo:

int[] a = {1,2,3,4};

for(int x = 0; x < a.length; x++)

System.out.print(a[x]);

>!El nuevo:

for(int n : a)

System.out.print(n);

Page 14: Clase5 controldeflujo

For “mejorado” (III)

>!Declaración: la variable declarada debe ser de un tipo compatible con los elementos del array. Su ámbito será el bloque del bucle, y su valor será el del elemento actual del array.

>!Expresión: la expresión debe evaluar al array que queremos recorrer. Puede ser una variable o un método que retorne un array. El array puede ser de cualquier tipo: primitivos, objetos, incluso arrays de arrays.

Page 15: Clase5 controldeflujo

Ejemplos de for “mejorado”

// Declaración de arrays int x;

long x2;

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

long [] la = {7L, 8L, 9L};

int [][] twoDee = {{1,2,3}, {4,5,6}, {7,8,9}};

String [] sNums = {"one", "two", "three"};

Animal [] animals = {new Dog(), new Cat()};

Page 16: Clase5 controldeflujo

Ejemplos de for “mejorado” (II)

// declaraciones legales

for(long y : la ) ;

for(long lp : La) ; // autounboxing

for(int[] n : twoDee) ;

for(int n2 : twoDee[2]) ; // 3er sub-array

for(String s : sNums) ;

for(Object o : sNums) ;

for(Animal a : animals) ;

Page 17: Clase5 controldeflujo

Ejemplos de for “mejorado” (III)

// declaraciones ilegales for(x2 : la) ; // x2 ya está

//declarado

for(int x2 : twoDee) ; // no puedo

//colocar un array en un int

for(int x3 : la) ; // no puedo

//poner un long en un int

for(Dog d : animals) ; //no todos

//eran perros

Page 18: Clase5 controldeflujo

break y continue

>!Las palabras clave break y continue se usan, respectivamente, para detener un bucle completo o solo la iteración actual.

>!La diferencia entre ellas es si continuamos con una nueva iteración del loop o desde la sentencia que se encuentra directamente debajo del ciclo.

Page 19: Clase5 controldeflujo

Continue

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

System.out.println("Inside loop");

if (foo.doStuff() == 5) {

continue;

}

// código que no

//será alcanzado si

//se ejecuta el

//continue

}

Page 20: Clase5 controldeflujo

Break

boolean problem = true;

while (true) {

if (problem) {

System.out.println("There was a

problem");

break;

}

}

// la ejecución continúa en este punto

Page 21: Clase5 controldeflujo

Pregunta boolean problem = true;

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

while (true) {

if (problem) {

System.out.println("There was a

problem");

break;

System.out.println(“a”);

}

}

}

>!¿Cuál es el resultado de este código?

Page 22: Clase5 controldeflujo

Etiquetas

>!Las sentencias break y continue pueden ser “etiquetadas” o “no etiquetadas”.

>!En el examen, se espera que conozcamos como funcionan las sentencias etiquetadas.

>!De colocarse, la etiqueta debe ir antes de la sentencia que queremos etiquetar, y consiste en un identificador valido, seguido de dos puntos (‘:’).

Page 23: Clase5 controldeflujo

Break con etiquetas

boolean isTrue = true;

outer:

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

while (isTrue) {

System.out.println("Hello");

break outer;

} // fin del while

System.out.println("Outer loop."); // no se imprime

} // fin del for

System.out.println("Good-Bye");

Page 24: Clase5 controldeflujo

Continue con etiquetas

outer:

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

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

System.out.println("Hello");

continue outer;

} // fin del ciclo interior

System.out.println("outer"); // no se imprime

}

System.out.println("Good-Bye");

Page 25: Clase5 controldeflujo

Pregunta boolean problem = true;

outer:

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

while (true) {

if (problem) {

System.out.println("There was a

problem");

break outer;

System.out.println(“a”);

}

}

}

>!¿Cuál es el resultado de este código? ¿Dónde continúa?

Page 26: Clase5 controldeflujo

Manejo de Excepciones

>!El “try” se usa para definir un bloque de código en el que pueden ocurrir excepciones. Este bloque de código se llama “región cautelosa” (lo cual significa que el “código riesgoso se coloca aquí”).

>!Una o más clausulas “catch” emparejan cada excepción con el bloque de código que las maneja.

Page 27: Clase5 controldeflujo

Manejo de Excepciones (II)

try {

// Código que podría arrojar una excepción

}

catch(MyFirstException) {

// Código que trata la excepción “MyFirstException”

}

catch(MySecondException) {

// Código que trata la excepción “MySecondException”

}

// Código que no arroja excepciones

Page 28: Clase5 controldeflujo

Pregunta

System.out.println(1/0.0);

System.out.println(-1/0.0);

System.out.println(Math.sqrt(-1));

System.out.println(1/0);

System.out.println(“Hello”);

System.out.printf("%d+ %d", 123,

456);

>!¿Qué imprime?

Page 29: Clase5 controldeflujo

Manejo de excepciones (III)

>!Nótese que si ocurre una excepción, el resto de las líneas del bloque “try” nunca se ejecutarán.

>!Una vez que el control pasa al bloque “catch”, nunca retorna al bloque try.

Page 30: Clase5 controldeflujo

class Plane {

static String s = "-";

public static void main(String[] args){

new Plane().s1();

System.out.println(s); }

void s1() {

try { s2(); }

catch (Exception e) {s += "c"; }}

void s2() throws Exception {

s3(); s += "2";

s3(); s += "2b"; }

void s3() throws Exception {

throw new Exception();} }

>!¿Cuál es el resultado de este código?

Page 31: Clase5 controldeflujo

finally

>!Un bloque finally contiene código que siempre se ejecuta luego del bloque try, sin importar si hubo o no una excepción.

>!Incluso si hay un return, el bloque finally se ejecuta luego de que la JVM encuentra el return, pero antes de que este se ejecute.

Page 32: Clase5 controldeflujo

1.! public class Test {

2.! public static String output =””;

3.! public static void foo(int i) {

4.! try {

5.! if(i==1)

6.! { throw new Exception(); }

7.! output += “1”;

8.! } catch(Exception e) {

9.! output += “2”;

10.! return;

11.! } finally {

12.! output += “3”;

13.! }

14.! output += “4”;

15.! }

16.! public static void main(String args[]) {

17.! foo(0);

18.! foo(1); } } ¿Cuál es el valor de output en la línea 18?

?

Page 33: Clase5 controldeflujo

Orden de try, catch, finally

>!try -catch== OK.

>!try-finally== OK.

>!try -catch-finally== OK.

>!try-finally -catch!= OK.

>!Solo try!= OK.

>!Solo catch!= OK.

>!Solo finally!= OK.

>!try-algo–catch!= OK.

Page 34: Clase5 controldeflujo

Propagando excepciones no atrapadas

>!Si nuestro programa comienza en un método main(), y main() llama a un método a(), que llama a un método b(), que a su vez llama a un método c(), la pila de llamadas consistirá de:

c

b

a

main

>!Las excepciones son como pelotas que se arrojan de persona a persona, empezando desde la azotea.

Page 35: Clase5 controldeflujo

Definiendo excepciones

>!Cada excepción es una instancia de una clase que posee la clase Exception en su jerarquía.

>!Cuando una excepción es arrojada, se crea un objeto de un subtipo de Exception, que se pasa como parámetro a la clausula catch del manejador de dicha excepción.

Page 36: Clase5 controldeflujo

Jerarquía de excepciones

>!Generalmente, nuestra aplicación no podrá recuperarse de un Error.

>!Las excepciones representan en general, ausencia de recursos.

>!Las RuntimeExceptions suelen indicar errores en el programa.

Page 37: Clase5 controldeflujo

Atrapar distintas excepciones

>!Podemos atrapar más de una excepción en una única cláusula catch.

>!Por ejemplo: FileNotFoundException es una subclase de IOException. Por lo tanto, podemos atraparla tanto en una cláusula que atrape todos los subtipos de IOException, como creando una cláusula especifica para FileNotFoundException.

Page 38: Clase5 controldeflujo

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(FileNotFoundException e) {

System.err.println("File not found");

System.err.println(e.getMessage());

e.printStackTrace();

}

catch(IOException e) {

System.err.println("IO Error");

System.err.println(e.toString());

e.printStackTrace();

}

}

Page 39: Clase5 controldeflujo

Atrapar distintas excepciones (II)

>!Es importante notar que la cláusula catch para la excepción “FileNotFoundException”, se encontraba arriba de la cláusula para la excepción “IOException”.

>!Si estuviesen al revés, sucedería algo como:

java.io.FileNotFoundException has

already been caught }

catch (FileNotFoundException ex) {

Page 40: Clase5 controldeflujo

Métodos para manejar excepciones

>!try/ catch

>!throws

>!Cada método debe tratar las excepciones (checked) proveyendo una clausula catch o bien declarar que es posible que arroje una excepción.

Page 41: Clase5 controldeflujo

Declaración de excepciones

>!Supongamos que nuestro método no arroja una excepción directamente, pero llama a un método que sí lo hace. Podemos elegir no tratar la excepción en nuestro método.

>!Para esto, declaramos la excepción que podría surgir, pero no proveemos cláusulas try/catch.

void myFunction() throws

MyException{

// código del método }

Page 42: Clase5 controldeflujo

Pregunta

void doStuff() {

doMore();

}

void doMore() throws IOException{

throw new IOException();

}

>!¿Compila? ¿Hay algo mal?

Page 43: Clase5 controldeflujo

RuntimeException

public void myMethod3() {

//código que podría arrojar una

NullPointerException

}

>!Las excepciones que heredan de RuntimeException se llaman “unchecked exceptions” y, como su nombre indica, no es necesario tratarlas o declararlas.

Page 44: Clase5 controldeflujo

Algo más sobre excepciones

public void test1() throws A{

throw new B();

} // Puede ser del mismo tipo que A o menor

class Parent {

public void test2() throws Exception{}

}

class Child extends Parent {

public void test2() throws

ArithmeticException{}

} // Debe ser del mismo tipo o menor

Page 45: Clase5 controldeflujo

Errores

>!Heredan de Throwable (pueden arrojarse usando “throws”), pero son unchecked.

>!Podríamos atraparlos, pero en general es demasiado tarde.

>!Por ejemplo, si tuviésemos un “OutOfMemoryError” o un “VirtualMachineError”, ¿Qué podríamos hacer?

Page 46: Clase5 controldeflujo

Assertions

>!Mientras probamos nuestro programa, validamos nuestras asunciones utilizando prints, sentencias if/else, manejadores de excepciones, etc.

>!¡Y después hay que sacarlos!

>!Utilizando assertions, podremos validar nuestro programa sin quitar nada luego.

Page 47: Clase5 controldeflujo

Assertions (II)

>!Los assertions funcionan de forma sencilla. Siempre asumimos que son true. Si lo son, no hay problema, el programa continúa su ejecución. Si son false, ocurre un AssertionError. private void methodA(int num) {

assert (num>=0);

useNum(num+ x);

}

Page 48: Clase5 controldeflujo

Assertions (III)

private void doStuff() {

assert (y > x): "y is " + y + " x

is " + x;

// código que asume que y es mayor

que x

}

>!El resultado de esta expresión se agrega a la traza de la pila. Ambas versiones arrojan un error AssertionError inmediatamente, pero la versión simple nos da algo mas de ayuda en el debugging.

Page 49: Clase5 controldeflujo

void noReturn() { }

int aReturn() { return 1; }

void go() {

int x = 1;

boolean b = true;

// Asserts legales:

assert(x== 1);

assert(b);

assert true;

assert(x== 1) : x;

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

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

Assertions (IV)

Page 50: Clase5 controldeflujo

Assertions (V)

// Asserts ilegales

// no son booleans

assert(x = 1);

assert(x);

assert 0;

assert(x== 1) : ;

// no retornan un valor

assert(x== 1) : noReturn() -void;

assert(x== 1) : ValidAssert va;

Page 51: Clase5 controldeflujo

Habilitando Assertions

>!Los assertions pueden habilitarse o desabilitarse a elección. Por defecto, están deshabilitados.

>!Para ejecutar un programa con assertions habilitados:

>!java -ea TestClass

>!java -enableassertions TestClass

Page 52: Clase5 controldeflujo

Deshabilitar assertions

>!Para deshabilitar los assertions:

>!java -daTestClass

>!java -disableassertions TestClass

>!Este comando puede parecer innecesario….

Page 53: Clase5 controldeflujo

Habilitación selectiva

>!Podemos combinar los comandos para, por ejemplo, deshabilitar las assertions en una única clase, pero habilitarlas en todas las otras. >!java -ea -da:com.geeksanonymous.Foo

>!Podemos usar un nombre de paquete (de esta

forma se deshabilita también en todos los

subpaquetes).

>!java -ea -da:com.geeksanonymous...

Page 54: Clase5 controldeflujo

Usando assertions correctamente

>!AssertionError es una subclase de Throwable, por lo que puede ser capturada. Pero no debemos hacerlo.

>!No debemos usar assertions para validar argumentos en métodos públicos:

public void doStuff(intx) {

assert (x > 0); // inapropiado

}

>!De la misma forma, no debemos usar assertions para validar argumentos en la línea de comandos.

Page 55: Clase5 controldeflujo

Usando assertions correctamente (II)

>!Debemos usar assertions para validar argumentos en métodos privados:

private void doMore(int x) {

assert (x > 0);

// código que utiliza x asumiendo

que es mayor que 0

}

Page 56: Clase5 controldeflujo

Usando assertions correctamente (III)

>!Podemos usarlas de esta forma:

switch(x) {

case 1: y = 3;

case 2: y = 9;

case 3: y = 27;

default: assert false;

// No se supone que lleguemos hasta

aquí

}

Page 57: Clase5 controldeflujo

No usar assertions que causen efectos secundarios

>!No está garantizado que las expresiones con asserts se ejecuten siempre, por lo tanto, no queremos que nuestro código se comporte de forma distinta dependiendo si las assertions están o no habilitadas. public void doStuff() {

assert (modifyThings());

}

public boolean modifyThings() {

y = x++;

return true; }

Page 58: Clase5 controldeflujo

Nota

Si en el examen aparece la palabra “apropiado”, no debemos confundirla

con “legal”. “Apropiado” se refiere a lo forma en la que se SUPONE que algo

debe ser usado, mientras que “legal” se refiere a la forma en la que algo PUEDE

ser usado.

Page 59: Clase5 controldeflujo

Preguntas