Publicado el Domingo 10 de junio de 2007 a las 07:40:01 por sedica
Lecturas
Algunos errores ocurren en ciertos casos que no hemos creidoque pudieran llegar a pasar. Por eso he decidido poner algunos truquillos que ayuden a detectarlos y pido a los lectores que amplien este artículo con más trucos y consejos.
1º- Evitar asignaciones en los bloques if, while, ...
Ejemplo:
if(opcion=5){ ... }
El problema aquí es que opcion toma el valor cinco y entra en el bloque de la condición siempre, independientemente de lo que valiera antes.
La solución es tan simple como que el orden de los factores no altera el resultado a la hora de comparar:
if(5=opcion){ ... }
En este caso el compilador se quejaría al querer asignar un valor a una constante.
2º- Comparación de cadenas de caracteres:
if( str.equals("Hola") ){ ... }
A simple vista parece que no puede haber problema alguno, pero ¿que pasatia si la cadena str apuntara a null? Pues que se lanzaría una excepcion por la llamada a un metodo de un objeto sin inicializar y rompería con la ejecucion del proceso.
¿Como solucionarlo? Usando el otro objeto a comparar, es decir, "Hola"; puesto que es un objeto que siempre va a estar declarado e inicializado, y cuyo metodo equals no falla por pasarle un parametro nulo.
if( "Hola".equals(str) ){ ... }
3º- Sembrado de sentencias
Este es el sistema por excelencia. Consiste en hacer que imprima mensajes para conocer que instrucciones se está ejecutando.
Lo óptimo sería que en cada mensaje se especifique cual ha sido la instrucción siguiente a ejecutar y además se impriman los datos de las variables afectadas.
En proyectos grandes esto podría llegar a resultar un caos, así que se puede hacer una variante que consiste en imprimir todos esos mensajes a un fichero de texto.
Tambien sería ideal que en vez de usar el mítico System.out.println() se use una función tal que:
/* ... */ public static final boolean DEBUG_ON=true;
public void debug(String s){ if(DEBUG_ON) System.out.println(s); // O la insercion de dicho mensaje a un fichero. }
De esta forma con cambiar el valor de true a false, ya conseguiríamos que se muestren o no dichos mensajes.
Insisto que en cada mensaje debe ser descriptivo de la situación.
Ejemplo:
public float test(){ debug("Funcion test()"); int a,b,c; a=1; b=2; c=0; debug("return (a+b)/c; a="+a+"; b="+b+"; c="+c+";"); return (a+b)/c; }
4º- Manejo de excepciones
Toda funcion debería lanzar o manejar las posibles excepciones que pudiera ocurrir, evitando dejar a su libre albedrío los diversos problemas que pudieran ocurrir. Como este es un tema bastante amplio, me limitaré a un caso general de manejo de las excepciones que consiste en el uso de un bloque try{...}catch(){} que se puede usar casi siempre.
Lo más indicado para meter en el bloque catch seria esto: try{ ... }catch(Exception e){ e.printStackTrace(); }
Esto lo que hace es que a la hora de que salte una excepcion, imprima un informe indicando que excepcion se ha lanzado, un mensaje explicativo (a veces no muy explicativo) y la representación de la pila de funciones, esto es saber que linea estaba ejecutando cierta funcion, la clase a la que pertenece esa funcion, el fichero de esa clase, etc. ¿Y por qué salen varias funciones? Facil, porque una funcion habrá llamado a otra y esa a otra etc... De todas esas lineas solo nos interesarán las que esten asociadas a clases nuestras. De esta forma sabremos que linea ha producido el fallo, porque se ha producido, quien llamo a ese metodo, etc..., información más que útil para poder solucionar los errores que puedan ocurrir.
1. ¿Qué pasaría si reemplazamos && por & en el siguiente bloque de código?
String a=null;
if (a!=null && a.length()>10) {...}
R. El ampersand simple causaría una excepción de tipo NullPointerException.
2. ¿Cuál es la principal diferencia entre un objeto Vector y un ArrayList?
R. La clase Vector está sincronizada internamente y la clase ArrayList no.
3. ¿Cómo puede forzarse al llamado del Garbage Collector?
R. No se puede forzar al GC pero si se puede solicitar por medio del llamado System.gc(); Sin embargo la JVM no garantiza que el GC sea iniciado inmediatamente
Hola, muy interesante tu propuesta, pero creo que se te esta pasando el mayor de los errores al empezar a programar, y es no tener una disciplina.
Primero hay que pensar antes de empezar a codificar, una vez que se tenga la solucion, se empieza a codificar, quiero hace enfasis en la importancia de la Ingenieria de Software, o no nos vayamos tan lejos, todos los dolores que unos diagramaticas te pueden ahorrar, si no saben diagramas UML, creo que en todos lados ensenian pseudocodigo o diagramas de flujo, lo que sea, pero siempre piensen antes de actuar, pregunten y pregunten, antes de escribir el primer if, les tiene que quedar claro que van a hacer, y para que, no que conozcan todo el negocio, pero si donde y como afecta su trabajo. Esa es la recomendacion que yo les puedo dar para disminuir errores.
Roberto Carlos, eso es cierto, pero la idea del artículo es detectar esos errores que suelen pasar en algunos casos por no haber pensado en ciertas situaciones, o por despistes a la hora de escribir el codigo, ya que puedes tener impecable el pseudocódigo pero a la hora de hacer el fuente, pues por unas causas o por otras (paranoias, suposiciones, etc...) escribes algo que parece que va a actuar como se espera pero no es así.