1. SCJP 6
Clase 5 – Control de Flujo,
Exceptions y Assertions
Ezequiel Aranda
Sun Microsystems Campus
Ambassador
2. 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/
3. AGENDA
>!f
i
>! or
f
>! or “mejorado”
f
>! reak y continue
b
>! xcepciones
e
>! ssertions
a
4. if
>! bserven este ejemplo:
O
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!");
>! l “else” pertenece al segundo “if”
E
5. 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.
6. Switch
>! na expresión en un switch debe evaluar a
U
un char, byte, short, int o, a partir de Java 5,
un enum.
>! na constante en un case debe evaluar al
U
mismo tipo que la expresión puede usar.
>! witch solo chequea igualdad.
S
>! uede colocarse el caso por defecto arriba.
P
7. Switch (II)
>! na vez que se encuentra una
U
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");
}}
8. While
>! ualquier variable a ser utilizada en la
C
expresión del bucle while debe ser declarada
antes de la evaluación de la expresión.
while (int x = 2) { } // no legal
>! l punto clave a recordar del while es que
E
podría no ejecutarse nunca.
9. Bucles
>! jemplos de salidas forzadas de los bucles
E
son:
break
return
System.exit()
exception
>! os cuales causan que un loop termine
L
abruptamente, sin ejecutar la expresión de la
iteración.
10. For
>! as variables declaradas en la sentencia “for”
L
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);
}
11. For (II)
>! l último detalle a destacar sobre el “for” es
E
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;
}
12. For “mejorado”
>! l nuevo for incluido en Java 5 es una forma
E
especializada del bucle que simplifica la tarea
de recorrer arrays o collections.
>! n vez de tener tres componentes, tiene solo
E
dos.
int[] a = {1,2,3,4};
for(int n : a)
System.out.print(n);
13. For “mejorado” (II)
>! l viejo:
E
int[] a = {1,2,3,4};
for(int x = 0; x < a.length; x++)
System.out.print(a[x]);
>! l nuevo:
E
for(int n : a)
System.out.print(n);
14. For “mejorado” (III)
>! eclaración: la variable declarada debe ser de
D
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.
>! xpresión: la expresión debe evaluar al array
E
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.
15. 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()};
16. 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) ;
17. 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
18. break y continue
>! as palabras clave break y continue se usan,
L
respectivamente, para detener un bucle
completo o solo la iteración actual.
>! a diferencia entre ellas es si continuamos
L
con una nueva iteración del loop o desde la
sentencia que se encuentra directamente
debajo del ciclo.
19. 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
}
20. Break
boolean problem = true;
while (true) {
if (problem) {
System.out.println("There was a
problem");
break;
}
}
// la ejecución continúa en este punto
21. 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?
¿
22. Etiquetas
>! as sentencias break y continue pueden ser
L
“etiquetadas” o “no etiquetadas”.
>! n el examen, se espera que conozcamos
E
como funcionan las sentencias etiquetadas.
>! e colocarse, la etiqueta debe ir antes de la
D
sentencia que queremos etiquetar, y consiste
en un identificador valido, seguido de dos
puntos (‘:’).
23. 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");
24. 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");
25. 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?
26. Manejo de Excepciones
>! l “try” se usa para definir un bloque de
E
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í”).
>! na o más clausulas “catch” emparejan cada
U
excepción con el bloque de código que las
maneja.
27. 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
29. Manejo de excepciones (III)
>! ótese que si
N
ocurre una
excepción, el resto
de las líneas del
bloque “try”
nunca se
ejecutarán.
>! na vez que el control pasa al bloque “catch”,
U
nunca retorna al bloque try.
30. 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?
¿
31. finally
>! n bloque finally contiene código que
U
siempre se ejecuta luego del bloque try, sin
importar si hubo o no una excepción.
>! ncluso si hay un return, el bloque finally se
I
ejecuta luego de que la JVM encuentra el
return, pero antes de que este se ejecute.
32. 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?
33. Orden de try, catch, finally
>! ry -catch== OK.
t
>! ry-finally== OK.
t
>! ry -catch-finally== OK.
t
>! ry-finally -catch!= OK.
t
>! olo try!= OK.
S
>! olo catch!= OK.
S
>! olo finally!= OK.
S
>! ry-algo–catch!= OK.
t
34. 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.
35. Definiendo excepciones
>! ada excepción es una instancia de una clase
C
que posee la clase Exception en su jerarquía.
>! uando una excepción es arrojada, se crea un
C
objeto de un subtipo de Exception, que se
pasa como parámetro a la clausula catch del
manejador de dicha excepción.
36. Jerarquía de excepciones
>! eneralmente, nuestra
G
aplicación no podrá
recuperarse de un Error.
>! as excepciones representan
L
en general, ausencia de
recursos.
>! as RuntimeExceptions
L
suelen indicar errores en el
programa.
37. Atrapar distintas excepciones
>! odemos atrapar más de una excepción en
P
una única cláusula catch.
>! or ejemplo: FileNotFoundException es una
P
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.
39. Atrapar distintas excepciones (II)
>! s importante notar que la cláusula catch
E
para la excepción “FileNotFoundException”,
se encontraba arriba de la cláusula para la
excepción “IOException”.
>! i estuviesen al revés, sucedería algo como:
S
java.io.FileNotFoundException has
already been caught }
catch (FileNotFoundException ex) {
40. Métodos para manejar
excepciones
>! ry/ catch
t
>! hrows
t
>! ada método debe tratar las
C
excepciones (checked) proveyendo
una clausula catch o bien declarar
que es posible que arroje una
excepción.
41. Declaración de excepciones
>! upongamos que nuestro método no arroja
S
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.
>! ara esto, declaramos la excepción que
P
podría surgir, pero no proveemos cláusulas
try/catch.
void myFunction() throws
MyException{
// código del método }
43. RuntimeException
public void myMethod3() {
//código que podría arrojar una
NullPointerException
}
>! as excepciones que heredan de
L
RuntimeException se llaman “unchecked
exceptions” y, como su nombre indica, no es
necesario tratarlas o declararlas.
44. 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
45. Errores
>! eredan de Throwable
H
(pueden arrojarse usando
“throws”), pero son
unchecked.
>! odríamos atraparlos, pero en general es
P
demasiado tarde.
>! or ejemplo, si tuviésemos un
P
“OutOfMemoryError” o un
“VirtualMachineError”, ¿Qué podríamos
hacer?
46. Assertions
>! ientras probamos nuestro programa,
M
validamos nuestras asunciones utilizando
prints, sentencias if/else, manejadores de
excepciones, etc.
>! Y después hay que sacarlos!
¡
>! tilizando assertions, podremos validar
U
nuestro programa sin quitar nada luego.
47. Assertions (II)
>! os assertions funcionan de forma sencilla.
L
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);
}
48. Assertions (III)
private void doStuff() {
assert (y > x): "y is " + y + " x
is " + x;
// código que asume que y es mayor
que x
}
>! l resultado de esta expresión se agrega a la
E
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.
49. Assertions (IV)
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(); }
50. 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;
51. Habilitando Assertions
>! os assertions pueden habilitarse o
L
desabilitarse a elección. Por defecto, están
deshabilitados.
>! ara ejecutar un programa con assertions
P
habilitados:
>! ava -ea TestClass
j
>! ava -enableassertions TestClass
j
52. Deshabilitar assertions
>! ara deshabilitar los assertions:
P
>! ava -daTestClass
j
>! ava -disableassertions TestClass
j
>! ste comando puede parecer innecesario….
E
53. Habilitación selectiva
>! odemos combinar los comandos para, por
P
ejemplo, deshabilitar las assertions en una
única clase, pero habilitarlas en todas las
otras.
>!java -ea -da:com.geeksanonymous.Foo
>! odemos usar un nombre de paquete (de esta
P
forma se deshabilita también en todos los
subpaquetes).
>!java -ea -da:com.geeksanonymous...
54. Usando assertions correctamente
>! ssertionError es una subclase de Throwable,
A
por lo que puede ser capturada. Pero no
debemos hacerlo.
>! o debemos usar assertions para validar
N
argumentos en métodos públicos:
public void doStuff(intx) {
assert (x > 0); // inapropiado
}
>! e la misma forma, no debemos usar
D
assertions para validar argumentos en la
línea de comandos.
55. Usando assertions correctamente (II)
>! ebemos usar assertions para validar
D
argumentos en métodos privados:
private void doMore(int x) {
assert (x > 0);
// código que utiliza x asumiendo
que es mayor que 0
}
56. Usando assertions correctamente (III)
>! odemos usarlas de esta forma:
P
switch(x) {
case 1: y = 3;
case 2: y = 9;
case 3: y = 27;
default: assert false;
// No se supone que lleguemos hasta
aquí
}
57. No usar assertions que causen
efectos secundarios
>! o está garantizado que las expresiones con
N
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; }
58. 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.