Errores comunes en Java

por | marzo 5, 2014

Java es un lenguaje minimalista, deliberadamente con menos características que otros lenguajes, nunca estas limitaciones tienen casos extremos con efectos extraños, algunos casos con efectos sorprendentes hace tropezar a los incautos. Si has leído otros lenguajes, puedes fácilmente leer Java de la manera incorrecta llevándote a la confusión.

Las variables solo son referencias o primitivas

Es correcto, las variables no son objetos. Esto significa que cuando ves lo siguiente:

[java]
String s = "Hello";
[/java]

s no es un objeto, no es un String, es una referencia a un String.

Esto responde a muchas áreas de confusión como:

  • Pregunta: Si un String es inmutable como puedo modificarlo. Ejm: s += «!»
  • Respuesta: Lo que cambia es la referencia al String.

== compara sus referencias, no su contenido

Para hacer mas grande la confusión, al usar == a veces funciona. Si se tiene dos valores inmutables que tienen el mismo contenido, la JVM puede intentar hacer la misma referencia. Ejm:

[java]
String s1 = "Hi", s2 = "Hi";
Integer a = 12, b = 12;
[/java]

En ambos casos, un pool de objetos es usado como referencia que al final termina apuntando al mismo lugar. s1 == s2 y a == b ambos objetos devuelven true porque la JVM ha hecho referencia al mismo objeto. Ahora, al variar un poco el código el pool de objetos no es el mismo y == devolverá false quizás de forma inesperada. En este caso se necesita usar equals().

[java]
String s3 = new String(s1);
Integer c = -222, d = -222;
[/java]
[java]
s1 == s2      // is true
s1 == s3      // is false
s1.equals(s3) // is true
a == b        // is true
c == d        // is false (diferentes objetos fueron creados)
c.equals(d)   // is true
[/java]

Para los Integer, el pool de objetos empieza en -128 hasta al menos 127(posiblemente mas)

Java pasa referencias por valor

Todas las variables son pasadas por valor, incluso las referencias. Esto significa que cuando se tiene una variable el cual es una referencia a un objeto, esta referencia es copiada, pero no el objeto. Ejm:

[java]
public static void addAWord(StringBuilder sb) {
sb.append(" word");
sb = null;
}
[/java]
[java]
StringBuilder sb = new StringBuilder("first ");
addWord(sb);
addWord(sb);
System.out.println(sb); // imprime "first word word"
[/java]

El objeto de referencia puede ser cambiado, pero los cambios a la referencia no tienen efecto en el objeto que lo llama.

En la mayoría de las JVM’s, el Object.hashCode() no tiene nada que ver con la posición en memoria.

Un hashCode() tiene que permanecer constante. Sin esto de facto, los hash de las colecciones como HashSet o ConcurrentHashMap no funcionarían. Sin embargo el objeto puede estar en cualquier lugar de la memoria y puede cambiar de lugar sin que el programa sepa que esto ha sucedido. Usar la posición para el hashcode() no funcionaría (a menos que se tenga una JVM donde los objetos no se muevan).

Para el OpenJDK y el HotSpot JVM el hascode() es generado bajo demanda y almacenado en la cabecera del objeto.

El Object.toString() hace algo sorprendentemente mas que útil.

El comportamiento por default de toString() es imprimir el nombre interno de la clase y un hashCode().
Como se ha mencionado, el hashCode() no es la ubicación en memoria a pesar que se ha impreso un hexadecimal. También para el nombre de la clase, especialmente con arrays es confuso. Por ejemplo un String[] se imprimirá como [Ljava.lang.String; El [ siginifica que es un array, la L significa que es un clase creada por un «lenguaje», no una primitiva como un byte el cual por cierto tiene un código de B; y el ; significa el final de la clase. Ejm:

[java]
String[] words = { “Hello”, “World” };
System.out.println(words);
[/java]

La salida es algo como esto:

[java]
[Ljava.lang.String;@45ee12a7
[/java]

Desafortunadamente se tiene que saber que la clase es un array de objetos, ejm. si se tiene un objeto words, se tiene un problema y se tiene que saber llamar a Arrays.toString(words) en su lugar. Esta encapsulación rota es una mala idea y una fuente común de confusión en StackOverflow.

Traducido de: http://www.javacodegeeks.com/2014/03/common-gotchas-in-java.html

Un pensamiento en “Errores comunes en Java

  1. Laura

    Estimado Sr. Ayala

    Con un cordial saludo, me permito indicar que el Ministerio de Telecomunicaciones a traves de la Subsecretaría de Telecomunicaciones y TIC desea contactarse telefonicamente con Usted.
    Por favor para mayor información le dejo mi número celular, agradeceremos se contacte con nosotros.

    Atentamente,
    Laura Castellanos
    Asistenet STTIC
    0995337687

Los comentarios están cerrados.