Está en la página 1de 14

Hable el lenguaje Java sin acento

Fluidez nativa para programadores no nativos

Elliotte Rusty Harold (elharo@metalab.unc.edu) 10-12-2012


Profesor adjunto
Polytechnic University

Elliotte Rusty Harold explora los modismos, dialectos y acentos nativos del lenguaje y la
comunidad Java™. Al seguir la orientación de este artículo, C/C++ y otros programadores no
nativos pueden mezclarse adecuadamente con los hablantes Java nativos.

Aprender un nuevo lenguaje de programación es más fácil que aprender un nuevo idioma
hablado. Pero, en ambos intentos, requiere esfuerzo extra aprender a hablar el lenguaje nuevo sin
acento. No es tan duro aprender el lenguaje Java cuando ya sabe C o C++. Es similar a aprender
danés cuando ya habla sueco. Los lenguajes son diferentes pero mutuamente comprensibles. Sin
embargo, si no es cuidadoso, su acento lo develará siempre como un hablante no nativo.

Los programadores C++ a menudo ponen ciertas inflexiones en el código Java que los marcan
indudablemente como conversos en lugar de hablantes nativos. Su código todavía funciona pero
suena mal al oído nativo. Como resultado, los nativos pueden menospreciar a los hablantes no
nativos. Cuando se pasa del C o C++ (o Basic o Fortran o Scheme o cualquier otro) al lenguaje
Java, es necesario erradicar ciertos modismos y corregir algunas pronunciaciones que usted
enuncia de manera fluida.

En este artículo, exploro una cantidad de detalles de programación Java que a menudo se pasan
por alto precisamente porque semánticamente no interesan demasiado, si es que interesan. Son
cuestiones puramente de estilo y convención. Algunas de ellas tienen justificaciones plausibles.
Algunas de ellas incluso carecen de eso. Pero todas ellas son fenómenos reales en el código
Java como está escrito actualmente.

¿Qué lenguaje es este?


Comencemos con un poco del código para convertir las temperaturas en Fahrenheit a
temperaturas en Celsius, que se muestra en el Listado 1:

© Copyright IBM Corporation 2012 Marcas


Hable el lenguaje Java sin acento Pagina 1 de 14
developerWorks® ibm.com/developerWorks/ssa/

Listado 1. ¿Un poco del código C?


float F, C; float min_tmp, max_tmp, x; min_tmp = 0; max_tmp = 300;
x = 20; F = min_tmp; while (F <= max_tmp) { C = 5 * (F-32) / 9;
printf("%f\t%f\n", F, C); F = F + x; }

¿Qué lenguaje se usa en el Listado 1? Evidentemente, es el C — pero espere un minuto. Observe


el programa completo en el Listado 2:

Listado 2. Un programa Java


class Test { public static void main(String argv[]) { float F, C;
float min_tmp, max_tmp, x; min_tmp = 0; max_tmp = 300; x = 20; F = min_tmp; while (F
<= max_tmp) { C = 5 * (F-32) / 9; printf("%f\t%f\n", F, C); F = F + x; } }
private static void printf(String format, Object... args) {
System.out.printf(format, args); } }

Créalo o no, los Listados 1 y 2 están escritos ambos en el lenguaje Java. Son solo códigos Java
escritos en un modismo C (para ser justos, el Listado 1 también podría ser un código C real). Pero
es un código Java de aspecto muy gracioso. Aquí una cantidad de modismos lo marcan como el
trabajo de alguien que piensa en C y está simplemente traduciendo al lenguaje Java:

• Las variables son floatsen lugar de doubles.


• Todas las variables se declaran al comienzo del método.
• La inicialización sigue a la declaración.
• Se usa un bucle while en lugar de un bucle for.
• printf se usa en lugar de println.
• El argumento para el método main() se llama argv.
• Los delimitadores de matriz vienen después del nombre del argumento en lugar de después
del tipo.

Ninguno de estos modismos es erróneo en el sentido de producir un código que no compilará


o que proporcione una respuesta incorrecta. Individualmente, ninguno de estos puntos es
significante. Sin embargo, en conjunto resultan en un código muy extraño que es tan difícil de
leer para un programador Java así como Geordie lo es para que un estadounidense lo entienda.
Mientras menos modismos C use, más claro será su código. Con eso en mente, analizaré algunos
de los modos más frecuentes en que los programadores C se develan a sí mismos y mostraré
cómo pueden hacer su código más agradable para el ojo Java.

Convenciones de denominación
Según si viene de C y C++ o C#, usted puede haber internalizado diferentes convenciones
de denominación para las clases. En C#, por ejemplo, los nombres de clase comienzan con
letras minúsculas y los nombres de método y campo comienzan con letras mayúsculas. El estilo
Java es exactamente al revés. No puedo justificar una convención u otro por cualquier motivo
racional pero sí sé que mezclar las convenciones de denominaciones hace que el código se
sienta terriblemente erróneo. También conduce a errores. Cuando sabe que cada nombre en
mayúsculas sostenidas es una constante, lo trata de modo diferente. He encontrado muchos

Hable el lenguaje Java sin acento Pagina 2 de 14


ibm.com/developerWorks/ssa/ developerWorks®

errores en programas al buscar simplemente lugares donde las convenciones de denominación


no coincidían con el tipo declarado.

args, no argv
Este punto es uno de los más triviales, pero esas son las minucias por las que se libran las
guerras de estilo. En la jerga Java, el argumento del método main() se llama args, no
argv:

public static void main(String[] args)


Esto es, en el mejor de los casos, solo una mejoría increíblemente pequeña del nombre
argv. Es ligeramente más evidente como una abreviación de argumentos. Por supuesto,
las abreviaciones están habitualmente prohibidas en el código Java idiomático (vea No
abrevie). La única razón por la que usamos args como el nombre del argumento para el
método main() es la misma razón por la que los programadores C usan argv — es lo que
Kernighan y Ritchie, las personas que escribieron el primer libro C, usaron. Gosling y Arnold
usan args. No hay otra razón que esa. Aun así, todos los programadores Java de habla
nativa prefieren argsy si usted quiere hablar sin acento, usted también lo preferirá.

Las reglas básicas para los nombres en la programación Java son bastante simples y valen la
pena memorizarlas:

• Los nombres de clase e interfaz comienzan con una letra mayúscula, como en Frame.
• Los nombres de método, campo y variable local comienzan con una letra minúscula, como en
read().
• Los nombres de clase, método y campo usan todos bicapitalización, como en InputStream y
readFully().
• Las constantes — campos estáticos finales y ocasionalmente variables locales finales
— se escriben todo en mayúsculas con subrayados que separan las palabras, como en
MAX_CONNECTIONS.

No abrevie
Los nombres como sprintf y nmtkns son reliquias de un tiempo en el que las supercomputadoras
tenían 32 KB de memoria. Los compiladores guardaban memoria al limitar los identificadores a 8
caracteres o menos. Sin embargo, esto no ha sido realmente un problema por más de 30 años.
Hoy no hay excusa para no escribir totalmente nombres de variables y métodos. Nada marca un
programa como el producto de un pirata informático C reformado de manera más evidente que los
incomprensibles nombres de variables sin vocales, como en el Listado 3:

Listado 3. Abbrvtd nms r hrd 2 rd


for (int i = 0; i < nr; i++) { for (int j = 0; j < nc; j++) {
t[i][j] = s[i][j]; } }

Los nombres sin abreviar en bicapitalización son mucho más legibles, como es posible observar
en el Listado 4:

Listado 4. Los nombres sin abreviar son fáciles de leer


for (int row = 0; row < numRows; row++) { for
(int column = 0; column < numColumns; column++) { target[row][column] =
source[row][column]; } }

Hable el lenguaje Java sin acento Pagina 3 de 14


developerWorks® ibm.com/developerWorks/ssa/

El código se lee más a menudo de lo que se lo escribe y el lenguaje Java se optimiza para la
lectura. Los programadores C tienen una atracción casi machista por el código ofuscado; los
programadores Java, no. El lenguaje Java prioriza la legibilidad sobre la concisión.

Algunas abreviaciones son tan comunes que es posible usarlas sin culpa.

• max de máximo
• min de mínimo
• in de InputStream
• out de OutputStream
• e o ex para una excepción en una cláusula catch (aunque en ningún otro lado)
• num de número, aunque solo cuando se usa como prefijo como en numTokenso numHits
• tmp para una variable temporal usada muy localmente — por ejemplo, cuando se
intercambian dos valores.

En otros casos, y tal vez en algunos otros, usted debería escribir todas las palabras completas
usadas en los nombres.

Declaración de la variable, inicialización y (re)utilización


Las primeras versiones de C necesitaban que todas las variables se declaren al comienzo del
método. Esto permitió ciertas optimizaciones en el compilador que le dejó ejecutarse en entornos
que eran bastante míseros con RAM: Así los métodos en C tienden a comenzar con varias líneas
de declaraciones de las variables:
int i, j, k; double x, y, z; float cf[], gh[], jk[];

Sin embargo, este estilo tiene una cantidad de efectos negativos. Separa la declaración de la
variable de su uso, lo que hace que el código sea un poco difícil de seguir. Además, hace mucho
más probable que una variable local sea reutilizada para varios fines diferentes, posiblemente de
modo involuntario. Esto puede introducir errores inesperados cuando una variable posee un valor
sobrante que una parte del código no estaba esperando. Combine esto con la inclinación de C por
los nombres de variables cortos y crípticos y obtendrá una receta para el desastre.

En el lenguaje Java (y versiones más recientes de C), las variables pueden declararse en o cerca
del punto de primer uso. Haga esto cuando escriba el código Java. Hace que su código sea más
seguro, menos propenso a errores y más fácil de leer.

En una nota relacionada, el código Java normalmente inicializa cada variable cuando y donde se
declara. Los programadores C a veces escriben el código del siguiente modo:
int i; i = 7;

Los programadores Java casi nunca escriben un código de esa forma, aunque sea
sintácticamente correcta. Ellos lo escriben de esta forma:
int i = 7;

Hable el lenguaje Java sin acento Pagina 4 de 14


ibm.com/developerWorks/ssa/ developerWorks®

Esto ayuda a evitar errores que resultan del uso involuntario de variables sin inicializar. La única
excepción común sucede cuando una sola variable necesita ser registrada en un bloque try y un
bloque catch o finally . Esto muy frecuentemente surge cuando el código trata con corrientes de
entrada y corrientes de salida que necesitan cerrarse en el bloque finally , como se muestra en
el Listado 5:

Listado 5. El manejo de excepciones puede hacer que sea difícil registrar


variables adecuadamente
InputStream in = null; try { in = new FileInputStream("data.txt"); // read from
InputStream } finally { if (in != null) { in.close(); } }

Sin embargo, ese es casi el único momento en que esto sucede.

Finalmente, el último efecto colateral de este estilo es que los programadores Java normalmente
declaran solo una variable por línea. Por ejemplo, inicializan tres variables del siguiente modo:
int i = 3; int j = 8; int k = 9;

Tienden a no escribir el código de esta forma:


int i=3, j=8, k=9;

Esta sentencia es sintácticamente correcta, pero los programadores Java a tiempo completo
habitualmente no hacen eso, excepto en un caso especial que mencionaré a continuación.

Un programador C de estilo antiguo puede incluso escribir el código en cuatro líneas:


int i, j, k; i = 3; j = 8; k = 9;

Así, el estilo Java habitual es en realidad un poco más conciso en solo tres líneas porque combina
declaración e inicialización.

Empuje las variables dentro de los bucles


Un caso especial que aparece frecuentemente es la declaración de variables fuera de los bucles.
Por ejemplo, considere el bucle simple for en el Listado 6, que calcula los primeros 20 términos
de la secuencia Fibonacci:

Listado 6. A los programadores C les gusta declarar variables fuera de los


bucles
int high = 1; int low
= 1; int tmp; int i; for (i = 1; i < 20; i++) { System.out.println(high); tmp =
high; high = high+ low; low = tmp; }

Las cuatro variables se declaran fuera del bucle y, por lo tanto, tienen un ámbito excesivo
aunque solo se usan dentro del bucle. Esto está propenso a errores porque las variables pueden
reutilizarse fuera del ámbito en el que se destinó para ser usadas Esto es especialmente cierto

Hable el lenguaje Java sin acento Pagina 5 de 14


developerWorks® ibm.com/developerWorks/ssa/

para las variables con nombres comunes tales como i y tmp. Los valores de un uso pueden
perdurar e interferir con el código posterior en maneras inesperadas.

La primera mejoría (que también está respaldada por versiones modernas de C) es mover la
declaración de la variable de bucle i dentro del bucle, como se muestra en el Listado 7:

Listado 7. Mueva variables de bucle adentro del bucle


int high = 1; int low = 1; int tmp; for (int i = 1; i
< 20; i++) { System.out.println(high); tmp = high; high = high+ low; low = tmp;
}

Sin embargo, no se detenga ahí. Los programadores Java experimentados también moverán la
variable tmp dentro del bucle, como en el Listado 8:

Listado 8. Declare variables temporales dentro de bucles


int high = 1; int low = 1; for (int i = 1;
i < 20; i++) { System.out.println(high); int tmp = high; high = high+ low; low =
tmp; }

Los estudiantes universitarios sin una obsesión excesiva por la velocidad a veces objetan que
esto reducirá la velocidad del código al realizar más trabajo de lo que es necesario dentro del
bucle. Sin embargo, al tiempo de ejecución, una declaración no realiza absolutamente ningún
trabajo. No hay sanción de rendimiento alguna en la plataforma Java por mover una declaración
dentro de un bucle.

Muchos programadores, que incluyen a programadores Java experimentados, se detendrán aquí.


Sin embargo, hay una técnica que se ha usado poco que mueve todas las variables dentro del
bucle. Es posible declarar en realidad más de una variable en la fase de inicialización de un bucle
for sencillamente al separarlas con comas, como se muestra en el Listado 9:

Listado 9. Todas las variables dentro del bucle


for (int i = 1, high = 1, low = 1; i < 20; i++) {
System.out.println(high); int tmp = high; high = high+ low; low = tmp; }

Esto ha pasado ahora más allá del código fluido meramente idiomático a un código
verdaderamente experto. Esta habilidad para limitar rigurosamente el ámbito de las variables
locales es una gran razón por la que usted ve mucho más bucles for y muchos menos bucles
while en código Java que en el código C.

No recicle las variables


Un corolario de lo anterior es que los programadores Java raras veces reutilizan las variables
locales para valores y objetos diferentes. Por ejemplo, el Listado 10 programa algunos botones
con ActionListeners asociados:

Hable el lenguaje Java sin acento Pagina 6 de 14


ibm.com/developerWorks/ssa/ developerWorks®

Listado 10. Reciclado de variables locales


Button b = new Button("Play"); b.addActionListener(new
PlayAction()); b = new Button("Pause"); b.addActionListener(new PauseAction()); b =
new Button("Rewind"); b.addActionListener(new RewindAction()); b = new
Button("FastForward"); b.addActionListener(new FastForwardAction()); b = new
Button("Stop"); b.addActionListener(new StopAction());

Los programadores Java experimentados reescriben esto con cinco variables locales diferentes,
como se muestra en el Listado 11:

Listado 11. Variables no recicladas


Button play = new Button("Play"); play.addActionListener(new
PlayAction()); Button pause = new Button("Pause"); pause.addActionListener(new
PauseAction()); Button rewind = new Button("Rewind"); rewind.addActionListener(new
RewindAction()); Button fastForward = new Button("FastForward");
fastForward.addActionListener(new FastForwardAction()); Button stop = new
Button("Stop"); stop.addActionListener(new StopAction());

La reutilización de una variable local para varios valores u objetos lógicamente diferentes está
propensa a errores. Esencialmente, las variables locales (aunque no siempre los objetos a los que
señalan) están libres de asuntos de memoria y tiempo. No tenga miedo de usar tantas variables
locales diferentes como sea necesario.

Confíe en el recopilador de basura para gestionar la


memoria
Los programadores que vienen del mundo C++ a menudo se preocupan excesivamente
sobre el consumo de memoria y las fugas de memoria. Existen dos síntomas comunes de
esto. Uno de ellos es la configuración de variables como nulas cuando termina de usarlas.
El otro es la invocación de finalize()o su utilización como un tipo de pseudodestructor.
Ninguno es necesario normalmente. Aunque hay momentos en los que realmente necesita
liberar memoria manualmente en código java, son pocos momentos y muy espaciados en el
tiempo. La mayoría del tiempo es posible simplemente contar con el recopilador de basura
para hacer algo sensato y razonablemente rápido. Como sucede con la mayoría de las
optimizaciones, la mejor regla general es: no las haga a menos, y hasta, que sea posible
demostrar que son necesarias.

Utilice los tipos de datos primitivos preferidos


El lenguaje Java tiene ocho tipos de datos primitivos pero solo se utilizan seis de ellos. En el
código Java, floatsson mucho menos comunes que en el código C. Casi nunca ve variables o
literales floats en el código Java; doublesse prefieren más. El único momento en que se usan
floatses en el manejo de grandes matrices multidimensionales de números de punto flotante con
precisión limitada en que el espacio de almacenamiento sería importante. Aparte de eso, solo
haga todo un doubles.

Incluso menos común que los floatsson los shorts.Raras veces he visto una variable short en
el código Java. En el único momento en el que aparece — y esto es extremadamente raro, le
advierto —, es cuando se leen formatos de datos externamente definidos que incluyen un tipo
entero firmado de 16 bits. En esa situación, la mayoría de los programadores solo leen eso como
un int.

Hable el lenguaje Java sin acento Pagina 7 de 14


developerWorks® ibm.com/developerWorks/ssa/

Ámbito de privacidad
¿Alguna vez ha visto un método equals() como el ejemplo en el Listado 12?

Listado 12. Un método equals() escrito por un programador C++


public
class Foo { private double x; public double getX() { return this.x; } public boolean
equals(Object o) { if (o instanceof Foo) { Foo f = (Foo) o; return this.x ==
f.getX(); } return false; } }

Este método es técnicamente correcto pero puedo prácticamente garantizarle que esta clase fue
escrita por un programador C++ recalcitrante. La señal delatora es el uso del campo privado x y
el método getter público getX() en el mismo método y efectivamente en la misma línea. En C+
+, esto es necesario porque la privacidad se registra en el ámbito del objeto en lugar de la clase.
Es decir, en C++, los objetos de la misma clase no pueden ver las variables asociadas privadas
de uno y otro. En cambio, deben usar métodos accessor. En el lenguaje Java, la privacidad se
registra en el ámbito de la clase en lugar del objeto. Dos objetos, cada uno de tipo Foo pueden
acceder directamente a los campos privados de uno y otro.

Algunas consideraciones sutiles — y más a menudo irrelevantes — sugieren que usted puede
preferir el acceso de campo directo antes del acceso getter o viceversa dentro del código Java.
El acceso de campo puede ser ligeramente más rápido, pero en raras ocasiones. Algunas
veces, el acceso getter puede brindar un valor un poco diferente del acceso de campo directo,
especialmente cuando las subclases están en juego. Sin embargo, en el lenguaje Java, nunca hay
ninguna excusa para usar ambos, acceso de campo directo y acceso getter, para el mismo campo
de la misma clase en la misma línea.

Modismos de puntuación y sintaxis


Aquí hay algunos modismos de Java que discrepan de sus homólogos C, en algunos casos para
aprovechar ciertas características del lenguaje Java.

Ubique delimitadores de matriz en el tipo


El lenguaje Java declara matrices del mismo modo que se hace en C:
int k[]; double temperature[]; String names[];

Sin embargo, el lenguaje Java también ofrece una sintaxis alternativa en la que los delimitadores
de matriz se ubican luego del tipo en lugar de luego del nombre de la variable:
int[] k; double[] temperatures; String[] names;

La mayoría de los programadores Java han adoptado el segundo estilo. Esto dice que k tiene la
matriz de tipo de int, temperatures tiene la matriz de tipo de doublesy names tiene la matriz de
tipo de Strings.

También, como con otras variables locales, los programadores Java tienden a inicializar la matriz
en el punto en el que se declara:

Hable el lenguaje Java sin acento Pagina 8 de 14


ibm.com/developerWorks/ssa/ developerWorks®

int[] k = new int[10]; double[] temperatures = new double[75];


String[] names = new String[32];

Use s == null, no null == s


Los cuidadosos programadores C han aprendido a colocar literales en el lado izquierdo de los
operadores de comparación. Por ejemplo:
if (7 == x) doSomething();

La meta aquí es evitar accidentalmente utilizar el operador de la asignación de iguales solos en


lugar del operador de comparación de iguales dobles:
if (7 = x) doSomething();

Ubicar el literal en el lado izquierdo hace que esto sea un error de tiempo de compilación. Esta
técnica es una buena práctica de programación en C. Ayuda a prevenir errores reales porque al
ubicar el literal en el lado derecho hace que esto siempre devuelva true.

Sin embargo, el lenguaje Java, a diferencia de C, tiene tipos separados int y boolean . El
operador de asignación devuelve un int, por cuanto el operador de comparación devuelve un
boolean. Por consiguiente, if (x = 7) ya es un error de tiempo de compilación, por lo que no
hay razón para utilizar la forma anormal if (7 == x) para sentencias de comparación y los
programadores Java fluidos no lo hacen.

Las cadenas concatenadas en lugar de formatearlas


Por muchos años, el lenguaje Java no tenía una función printf() . Esto se agregó finalmente
en Java 5 y tiene algunos usos ocasionales. En particular, las series de formato son un lenguaje
de dominio específico conveniente para los casos raros cuando usted quiere formatear números
para anchuras particulares o con una cierta cantidad de lugares luego del separador decimal.
Sin embargo, los programadores C tienden a usar excesivamente printf() en su código Java.
Generalmente, no se lo debería usar meramente como una sustitución de una concatenación de
cadena simple. Por ejemplo:
System.out.println("There were " + numErrors + " errors
reported.");

es preferible antes que:


System.out.printf("There were %d errors reported.\n",
numErrors);

La variante que usa la concatenación de cadena es más fácil de leer, en especial en casos
simples, y menos propenso a error porque no hay peligro de no coincidencia entre marcadores en
la serie de formato y la cantidad o el tipo de los argumentos variables.

Hable el lenguaje Java sin acento Pagina 9 de 14


developerWorks® ibm.com/developerWorks/ssa/

Preferencia del incremento posterior antes que el incremento previo


Hay lugares donde la diferencia entre i++ y ++i es importante. Los programadores Java tienen un
nombre especial para estos lugares. Se llaman "errores".

Usted nunca debería escribir un código que dependa de la diferencia entre el incremento previo
y el incremento posterior (y eso también es válido para C). Es simplemente muy difícil de seguir
y muy propenso al error. Si usted está escribiendo un código donde la diferencia sí importa,
entonces reorganice el código en sentencias separadas para que no importe más.

Donde la diferencia entre el incremento previo y el incremento posterior es insignificante — por


ejemplo, como en el paso de incremento de un bucle for—, los programadores Java prefieren el
incremento posterior antes que el incremento previo alrededor de 4 a 1. i++ es mucho más común
que ++i. No puedo justificar eso pero es así. Si escribe ++i, cualquiera que lea su código va a
perder tiempo preguntándose por qué lo escribió así. En consecuencia, debería usar siempre el
incremento posterior a menos que tenga una razón particular para usar el incremento previo (y
nunca debería tener una razón para usar el incremento previo).

Manejo de errores
El manejo de errores es una de las cuestiones que más se confunden en la programación
Java y una que realmente separa a los diseñadores maestros del lenguaje de los gruñones y
murmuradores. Efectivamente, podría fácilmente ser la base de un artículo en sí mismo. En pocas
palabras, use las excepciones adecuadamente y nunca devolverá códigos de error.

El primer error de los hablantes no nativos es devolver un valor que indica un error, en lugar
de arrojar una excepción. Efectivamente, puede incluso ver esto en algunos de los API propios
del lenguaje Java que se remontan a los primeros días de Java 1.0, antes de que todos los
programadores en Sun hubieran internalizado completamente el lenguaje nuevo. Por ejemplo,
considere el método delete() en java.io.File:
public boolean delete()

Este método devuelve true si el archivo o directorio se suprime con éxito. Si no, devuelve false.
Lo que debería hacer es no devolver nada cuando se finaliza con éxito y arrojar una excepción si
el archivo existe pero no se puede suprimir por alguna razón:
public void delete() throws IOException

Cuando los métodos devuelven valores de error, cada llamada de método está rodeada por un
código de manejo de errores. Esto hace que sea difícil de seguir y entender el flujo normal de
ejecución del método cuando, como normalmente es el caso, no hay problema y todo está bien.
En cambio, cuando las condiciones de error se indican por excepciones, el manejo de errores
puede sacarse del camino en un bloque de código separado más tarde en el archivo. Se lo puede
mover incluso a otros métodos y otras clases si existe un lugar más adecuado para manejar el
problema.

Hable el lenguaje Java sin acento Pagina 10 de 14


ibm.com/developerWorks/ssa/ developerWorks®

Esto me lleva al segundo antipatrón en el manejo de errores. Los programadores que vienen de
un ambiente C o C++ a veces intentan manejar excepciones tan cerca como sea posible hasta
el punto que se arroja la excepción. Tomado al extremo, puede resultar en un código como el
Listado 13:

Listado 13. Manejo de excepciones muy temprano


public void readNumberFromFile(String name) {
FileInputStream in; try { in = new FileInputStream(name); } catch
(FileNotFoundException e) { System.err.println(e.getMessage()); return; }
InputStreamReader reader; try { reader = new InputStreamReader(in, "UTF-8"); } catch
(UnsupportedEncodingException e) { System.err.println("This can't happen!"); return;
} BufferedReader buffer = new BufferedReader(reader); String line; try { line =
buffer.readLine(); } catch (IOException e) { System.err.println(e.getMessage());
return; } double x; try { x = Double.parseDouble(line); } catch
(NumberFormatException e) { System.err.println(e.getMessage()); return; }
System.out.println("Read: " + x); }

Esto es tan difícil de leer e incluso más intricado que las pruebas if (errorCondition) que el
manejo de excepciones fue diseñado para sustituir. El código Java fluido mueve el manejo de
errores fuera del punto de falla. No mezcla el código de manejo de errores con el flujo normal de
ejecución. La versión en el Listado 14 es mucho más fácil de seguir y entender:

Listado 14. Mantenga junto el código para la ruta principal de ejecución


public void
readNumberFromFile(String name) { try { FileInputStream in = new
FileInputStream(name); InputStreamReader reader = new InputStreamReader(in,
"UTF-8"); BufferedReader buffer = new BufferedReader(reader); String line =
buffer.readLine(); double x = Double.parseDouble(line); System.out.println("Read: "
+ x); in.close(); } catch (NumberFormatException e) { System.err.println("Data
format error"); } catch (IOException e) { System.err.println("Error reading from
file: " + name); } }

Ocasionalmente, usted puede necesitar usar bloques anidados try-catch para separar diferentes
modos de fallas que producen la misma excepción pero esto no es común. La regla general es
que si hay más de un valor de código del bloque tryen un método, entonces el método es muy
grande y probablemente debería dividirse en métodos más pequeños de todos modos.

Finalmente, los programadores nuevos en la programación Java de todos los lenguajes a menudo
cometen el error de asumir que deben obtener excepciones verificadas en el método donde se
arrojan. En muchas ocasiones, el método que arroja la excepción no es el método que debería
obtenerla. Por ejemplo, considere un método que copie secuencias, como en el Listado 15:

Listado 15. Manejo de excepciones muy temprano


public static void copy(InputStream in, OutputStream out)
{ try { while (true) { int datum = in.read(); if (datum == -1) break;
out.write(datum); } out.flush(); } catch (IOException ex) {
System.err.println(ex.getMessage()); } }

El método simplemente no tiene suficiente información para manejar plausiblemente las


IOExceptionsque pueden ocurrir. No sabe quién lo llamó y no sabe cuáles son las consecuencias

Hable el lenguaje Java sin acento Pagina 11 de 14


developerWorks® ibm.com/developerWorks/ssa/

de una falla. Lo único razonable para que este método haga es dejar que la IOException burbujee
hasta el interlocutor. El modo correcto para escribir este método se muestra en el Listado 16:

Listado 16. No todas las excepciones tienen que obtenerse en el primer


momento posible
public
static void copy(InputStream in, OutputStream out) throws IOException { while (true)
{ int datum = in.read(); if (datum == -1) break; out.write(datum); } out.flush();
}

Es más corto. Es más simple. Es más comprensible y transmite la información del error a la parte
del código que es más adecuado para manejarla.

¿Cuánto importa esto en realidad?


Ninguno de estos son problemas críticos. Algunos de ellos tienen motivo para la convención:
Declarar las variables en el punto del primer uso, arrojar excepciones cuando no sabe qué hacer
con ellas. Otros son de convención puramente estilística (args, no argv; i++ en lugar de ++i). No
voy a asegurar que seguir cualquiera de estas reglas hará que su código se ejecute más rápido y
solo algunas de ellas le ayudarán a evitar errores. Sin embargo, todas ellas son necesarias para
convertirse en un hablante Java con fluidez nativa.

Para bien o para mal, hablar (o escribir un código) sin acento causará que otros lo respeten más,
le presten más atención a lo que dice e incluso le paguen más para que lo diga. Además, hablar
el lenguaje Java sin acento en realidad es mucho más fácil que hablar francés, chino o inglés sin
acento. Una vez que usted haya aprendido el lenguaje, vale la pena hacer el esfuerzo extra para
hablarlo como lo haría un nativo.

Hable el lenguaje Java sin acento Pagina 12 de 14


ibm.com/developerWorks/ssa/ developerWorks®

Recursos
• Code Conventions for the Java Programming Language: Aunque es un poco anticuada, esta
referencia todavía sirve como la base para el estilo Java moderno.
• The Java Language Specification (James Gosling et al., Addison Wesley, 2005): Ahora en
su tercera edición, esta fue tal vez la primera especificación de lenguaje para reconocer que
se necesitaba debatir el estilo, así como también la sintaxis y la semántica. Es una razón
importante que el lenguaje Java tenga un estilo mucho más estándar a través de grupos y
proyectos que el que tienen los primeros lenguajes, como C++ y Basic.
• Effective Java, 2.º ed. (Joshua Bloch, Prentice Hall, 2008): El libro de Bloch cubre muchos de
los aspectos más semánticos del estilo Java.
• "Java programming for C/C++ developers" (James Stricker, developerWorks, mayo del
2002): Este tutorial está diseñado para programadores C o C++ que quieren aprender cómo
programar en el lenguaje Java.
• Lo nuevo en la programación Java: Lea una visión general de los conceptos básicos de la
tecnología Java y descubra cómo la tecnología se integra en el contexto del desarrollo de
software contemporáneo.
• Explore la technology bookstore para encontrar libros sobre estos y otros temas técnicos.
• Libreria Java en developerWorks: Encuentre cientos de artículos acerca de cada aspecto de
la programación Java.
• Participe en My developerWorks community.

Hable el lenguaje Java sin acento Pagina 13 de 14


developerWorks® ibm.com/developerWorks/ssa/

Sobre el autor
Elliotte Rusty Harold

Elliotte Rusty Harold es originariamente de Nueva Orleans, a donde regresa


periódicamente en busca de un tazón decente de gumbo. Sin embargo, reside en
el barrio Prospect Heights de Brooklyn con su esposa Beth y sus gatos Charm (por
el quark) y Marjorie (por su suegra). Es profesor adjunto de ciencias informáticas
en la Polytechnic University, en donde enseña tecnología Java y programación
orientada a objetos. Su website Cafe au Lait se ha convertido en uno de los sitios
Java independientes más populares de Internet, sitio derivado, Cafe con Leche, se
ha convertido en uno de los sitios XML más populares. Entre sus libros se incluyen
Effective XML, Processing XML with Java, Java Network Programming y The XML
1.1 Bible. Actualmente está trabajando en el XOM API para procesar XML, el motor
Jaxen XPath y la herramienta Jester de cobertura de pruebas.

© Copyright IBM Corporation 2012


(www.ibm.com/legal/copytrade.shtml)
Marcas
(www.ibm.com/developerworks/ssa/ibm/trademarks/)

Hable el lenguaje Java sin acento Pagina 14 de 14

También podría gustarte