2010-05-27 15 views
7

Referencia: http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html¿Por qué el autoboxing en Java me permite tener 3 valores posibles para un booleano?

"Si el programa intenta autounbox nula, se lanzará una NullPointerException."

javac le dará un error en tiempo de compilación si intenta asignar nulo a un booleano. tiene sentido. Sin embargo, la asignación de null a un booleano es a-ok. también tiene sentido, supongo.

pero pensemos en el hecho de que obtendrá un NPE cuando intente autouncar nulo. lo que esto significa es que no puede realizar operaciones booleanas de manera segura en Booleanos sin verificación nula o manejo de excepciones. Lo mismo aplica para hacer operaciones matemáticas en un Entero.

durante mucho tiempo, era un fanático del autoboxing en java1.5 + porque pensé que tenía Java más cerca para estar realmente orientado a objetos. pero, después de toparme con este problema anoche, debo decir que creo que esto apesta. el compilador que me da un error cuando trato de hacer cosas con un primitivo no inicializado es algo bueno. No quiero usar el autoboxing si pierdo eso.

Creo que puedo estar malinterpretando el punto de autoboxing, pero al mismo tiempo, nunca aceptaré que un boolean debería poder tener 3 valores. ¿Alguien puede explicar esto? ¿Qué no estoy recibiendo?

+0

Una pregunta de sí o no puede tener tres respuestas: sí, no, no sé. – ADTC

Respuesta

0

Autoboxing transforma automáticamente los tipos de datos entre los tipos intrínsecos y los tipos de objeto.

Los tipos de objeto para Boolean pueden ser Boolean.TRUE, Boolean.FALSE o null. Es por eso que tiene que lidiar con los 3 valores posibles para un booleano.

En las bases de datos, es común tener tres estados para un tipo booleano. Considere un registro que rastrea si alguien ha aprobado una clase. Hay VERDADERO, para pasar; FALSO por no pasar, y NULO por "tomar la clase actualmente". Sí, es extraño, pero no tener un valor es heredar en la programación orientada a objetos.

También encuentro el autoboxing un poco desagradable, principalmente porque es una característica donde el compilador agrega bytecode para manejar el proceso de conversión. En mi opinión, esto puede llevar a que las personas se olviden de detalles importantes en el proceso de conversión que podrían ser mejor recordados (como el manejo nulo en su caso). Es útil, pero no tan útil como la mayoría de las otras características del lenguaje Java.

Personalmente, deseo que los elementos intrínsecos se hayan implementado como objetos livianos en lugar de tipos "incorporados". Hay muchas veces en que el sistema de tipo intrínseco/objeto híbrido se interpone. Dicho esto, se suponía que los intrínsecos debían estar ahí para mejorar el rendimiento, pero parece que si tienes que hacer muchas cosas intrínsecas a la clasificación por objetos, no puedes disfrutar del aumento del rendimiento intrínseco únicamente.

16

Los tipos de caja son tipos de referencia, y todos los tipos de referencia, cuadros primitivos o no, pueden hacer referencia a null. Es por eso que un Boolean puede hacer referencia a null. Entonces puede un Integer. Lo mismo ocurre con un String, etc.

Los tipos de caja no están diseñados para hacer que Java esté realmente orientado a objetos. Java será nunca sea un lenguaje puramente orientado a objetos, y no debe codificar como si este fuera el caso. Los tipos primitivos nunca desaparecerán y, de hecho, deberían preferirse siempre que haya una opción.

Aquí es una cita de eficaz de Java 2ª edición, artículo 49: Prefiero tipos primitivos a los primitivos en caja (énfasis del autor):

En resumen, el uso de las primitivas en preferencia a caja primitiva cada vez que tenga la elección. Los tipos primitivos son más simples y rápidos. Si debe usar primitivos en caja, ¡tenga cuidado! El Autoboxing reduce la verbosidad, pero no el peligro, del uso de las primitivas en caja. Cuando su programa compara dos primitivas encuadradas con el operador ==, hace una comparación de identidad, que es casi seguro no lo que desea. Cuando su programa realiza cálculos mixtos que involucran primitivas en caja y sin caja, lo hace unboxing, y cuando su programa realiza unboxing, puede lanzar NullPointerException. Finalmente, cuando su programa contiene valores primitivos, puede generar creaciones de objetos costosas e innecesarias.

+0

es el principal problema con el autoboxing, o con auto-unboxing? Hay algunas veces cuando el autoboxing puede ser problemático (en mi humilde opinión, al realizar una resolución de sobrecarga para una función N-argument, el autoboxing debe deshabilitarse para el argumento Kth si el argumento Kth de * cualquier * sobrecarga de N-argumentos es primitiva), pero el auto-unboxing parece peligroso en la mayoría de las situaciones. – supercat

1

Creo que es una cuestión más filosófica que técnica. Cuando se transforma el tipo primitivo en tipo de referencia, debe estar preparado para que los tipos de referencia (es decir, los objetos) sean anulables.

Puede ver la presentación The Billion Dollars Mistake donde C.A.R. Hoare dice que su introducción de referencias nulas a oop (Algol 60) fue un error.

Josh Bloch en vigencia Java recomienda preferir tipos primitivos donde sea posible. Pero a veces tienes que verificar tu variable Boolean contra null.

0

En realidad, no hay una gran diferencia con respecto a los días previos a Java 1.5: el problema no es el tipo booleano (todavía tiene dos estados) sino el contenedor booleano (que siempre tenía 3 estados) Boolean.TRUE, Boolean.FALSE y nulo).

Cada conversión de un objeto booleano a la primitiva booleana requiere comprobaciones nulas, con o sin autoboxing.

5

Además de todo lo que aquí se menciona, hay casos en los que desea mucho tener un tercer valor para booleanos: el caso de una propiedad "opcional".

Generalmente lo encontramos con bases de datos, con columnas booleanas que permiten nulos. Sin usar Booleanos, necesitaríamos usar dos variables separadas, una indicando el valor y otra si es válida.

De hecho, si observa la API JDBC, puede ver un ejemplo de este problema, donde las columnas obtienen un valor predeterminado si son nulas (por ejemplo, un 0 para campos numéricos), y luego tiene que llamar "wasNull" para comprobar si es un verdadero 0 o falso nulo.

7

He visto al menos un caso en el que el valor null es útil. Muchos de los objetos de datos en los servicios web tienen campos booleanos nullable. A veces el usuario no incluye un valor. En este caso, desea poder discernir la falta de un valor a partir de un valor predeterminado. Anteriormente, las personas escribían los métodos getX, setX y isXSet(), donde isXSet devuelve falso hasta que alguien llame al setX. Ahora es posible hacer que X sea un tipo anulable y está claro que no se configuró si getX devuelve null.

0

Es el problema con el autoboxing, al igual que Integer i = null;. Integer objeto puede ser nulo mientras que un int nativo no puede ser.

4

Su problema es con auto un boxeo, no autoboxing. Creo autounboxing es el mal por razones más importantes:

Considera:

Integer i = new Integer(1); 
Integer i2 = new Integer(12); 

System.out.println(i == 10 || i != i2); 

Una == unboxes y el otro no lo hace.

Unboxing en operadores (en lugar de asignaciones) fue un error en mi opinión (dado lo anterior, simplemente no es Java). El boxeo, sin embargo, es muy bueno.

0

Nunca se pretendió, con la introducción del autoboxing, reemplazar las primitivas. En la mayoría de los lugares, los primitivos son lo que quieres. Si desea comenzar a utilizar los tipos de referencia porque "java java más cerca para estar realmente orientado a objetos", esa es su decisión, pero a medida que descubra, hay desventajas con ese enfoque. El rendimiento será otro problema.

Autoboxing (y autounboxing) está ahí para ayudar con las transiciones entre código que usa primitivas (la mayoría) y el código que tiene que usar tipos de referencia (raro). De los tipos de referencia, Boolean es, sin duda, el más raro, ya que su pequeño número de instancias significa que casi nunca vale la pena poner en una colección.

En resumen: si los tipos de referencia le causan problemas, no los use. Pero no digas 'el autoboxing es malo' solo porque resultaron no ser útiles en tu situación.

Cuestiones relacionadas