Ejemplos de código - Asignaciones

A continuación dejo unos ejemplos de código con explicaciones. Estos ejemplos surgieron a partir de la realización de los ejercicios del capítulo 3 (Assignments) del libro "Sun Certified Programmer for Java 6 Study Guide".
Para ver el post con el resumen de dicho capítulo haz click aquí.
Cada ejemplo tiene un link para visualizar el código original desde el proyecto (SVN) google.

EJEMPLO 1 (Ver código original)

01. class Alien {
02. String invade(short ships) { return "a few"; }
03. String invade(short... ships) { return "many"; }
04. }
05. public class Defender {
06. public static void main(String[] args) {
07. System.out.println(new Alien().invade(7));
08. }
09. }
/*
Defender.java:7: cannot find symbol
symbol : method invade(int)
location: class Alien
System.out.println(new Alien().invade(7));
^
1 error
*/

Al compilar el código anterior se produce un error en la línea 7. Esto sucede debido a que se pasa como argumento el valor 7. El literal 7 (a secas) es de tipo int. Como no existe ninguna versión del método invade() que tome un valor int, se genera el error "cannot find symbol".
Para que este ejemplo funcione correctamente es necesario realizar un casteo del literal 7 hacia el tipo short, como lo muestra la línea siguiente:
System.out.println(new Alien().invade((short) 7));
De este modo el programa se ejecutaría correctamente, y su salida sería:
a few

EJEMPLO 2 (Ver código original)

01. public class Dims {
02. public static void main(String[] args) {
03. int[][] a = {{1, 2, }, {3, 4}};
04. int[] b = (int[]) a[1];
05. Object o1 = a;
06. int[][] a2 = (int[][]) o1;
07. int[] b2 = (int[]) o1;
08. System.out.println(b[1]);
09. }
10. }
/*
Exception in thread "main" java.lang.ClassCastException: [[I cannot be cast to [
I
at Dims.main(Dims.java:7)
*/

Cuando se intenta compilar el código anterior la misma falla, debido a que (en la línea 7) se realiza una conversión erronea (ClassCastException). Esto se debe a que la variable o1 almacena una referencia a un arreglo de tipo int[][] y se intenta castear el mismo a uno de tipo int[].
Para visualizar la salida de este programa se podría comentar la línea 7, o reemplazarla con el código siguiente:
int[] b2 = (int[]) ((int[][]) o1)[0];
De esta manera lo que se hace es:
  1. Castear el objeto o1 hacia un arreglo de tipo int[][].
  2. Tomar el primer arreglo simple dentro del arreglo multidimensional (o1).
  3. Realizar una conversión explícita del arreglo al tipo int[] (la cuál es redudante, ya que se haría implicitamente).
  4. Finalmente se asigna a la variable de referencia b2 el valor de referencia del arreglo simple.

EJEMPLO 3 (Ver código original)

01. public class Bridge {
02. public enum Suits {
03. CLUBS(20), DIAMONDS(20), HEARTS(30), SPADES(30),
04. NOTRUMP(40) {
05. public int getValue(int bid) {
06. return ((bid-1)*30) + 40;
07. }
08. };
09. Suits(int points) {
10. this.points = points;
11. }
12. private int points;
13. public int getValue(int bid) {
14. return points * bid;
15. }
16. }
17. public static void main(String[] args) {
18. System.out.println(Suits.NOTRUMP.getValue(3));
19. System.out.println(Suits.SPADES + " " + Suits.SPADES.points);
20. System.out.println(Suits.values());
21. }
22. }
/*
SALIDA:
100
SPADES 30
[LBridge$Suits;@addbf1
*/

El ejemplo de código anterior tiene tres líneas de salida:
  1. El valor NOTRUMP del enum Suits tiene sobreescrito el método getValue(int bird). Es por este motivo que cuando se invoca el método getValue() no se invoca la versión orginal.
  2. La línea Suits.SPADES devuelve el valor de la constante como un String.
  3. El método values() sobre el enum Suits devuelve una referencia a un arreglo, es por esto que se muestra el valor de referencia en vez de mostrar los valores del enum.

EJEMPLO 4 (Ver código original)

01. public class Ouch {
02. static int ouch = 7;
03. public static void main(String[] args) {
04. new Ouch().go(ouch);
05. System.out.print(" " + ouch);
06. }
07. void go(int ouch) {
08. ouch++;
09. for(int ouch = 3; ouch < 6; ouch++)
10. ;
11. System.out.print(" " + ouch);
12. }
13. }
/*
Ouch.java:9: ouch is already defined in go(int)
for(int ouch = 3; ouch < 6; ouch++)
^
1 error
*/

Este error se genera debido a que se esta definiendo una variable con un nombre que ya existe para ese ámbito. Es decir, el nombre de la variable del parámetro del método go() es ouch, el error se genera al utilizar este mismo nombre dentro del bloque for (dentro del mismo método o mismo ámbito).

EJEMPLO 5 (Ver código original)

01. public class Bertha {
02. static String s = "";
03. public static void main(String[] args) {
04. int x = 4;
05. Boolean y = true;
06. short[] sa = {1, 2, 3};
07. doStuff(x, y);
08. doStuff(x);
09. doStuff(sa, sa);
10. System.out.println(s);
11. }
12. static void doStuff(Object o) { s += "1"; }
13. static void doStuff(Object... o) { s += "2"; }
14. static void doStuff(Integer... i) { s += "3"; }
15. static void doStuff(Long l) { s += "4"; }
16. }
/*
SALIDA:
212
*/

La salida del código de ejemplo anterior se genera a partir de tres invocaciones al método doStuff() con distintos parámetros:

'2': Resultado de la invocación de la línea 7. El método se invoca con un valor de tipo int y uno Boolean.
doStuff(Object... o): Para el argumento de tipo int se hace un autoboxing hacia el tipo Integer. Como Integer y Boolean cumplen la relación ES-UN con el tipo Object, esta es la versión que se ejecuta.
doStuff(Integer... i): Este método no se invoca debido a que el tipo Boolean NO ES-UN Integer.

'1': Resultado de la invocación de la línea 8. El método se invoca con un valor de tipo int.
doStuff(Object o): Para el argumento de tipo int se hace un autoboxing hacia el tipo Integer. Como Integer cumple la relación ES-UN con el tipo Object, esta es la versión que se ejecuta.
doStuff(Long l): Este método no se invoca debido a que el tipo Integer no cumple la relación ES-UN con el tipo Long.

'2': Resultado de la invocación de la línea 9. El método se invoca con dos argumentos de tipo short[].
doStuff(Object... o): Ambos argumentos son arreglos (es decir, objetos), los mismos se generalizan al tipo Object.
doStuff(Integer... i): Este método no se invoca debido a que el tipo short[] no cumple la relación ES-UN con el tipo Integer.

0 comentarios:



Publicar un comentario en la entrada

Este blog dejo de ser mantenido el día 12/02/2010. Para cualquier consulta o comentario realizarlo a través del sitio http://onj2ee.blogspot.com/