Pregunta

Mezcla el uso de tipos de datos simples y sus respectivas clases contenedoras, en Java, puede conducir a una gran cantidad de bugs.El siguiente ejemplo ilustra el problema:

int i = 4;
...
if (i == 10)
  doStuff();

Más tarde, en la figura que desea que la variable yo a ser definido o indefinido, por lo que el cambio de la por encima de la creación de instancias para:

Integer i = null;

Ahora la comprobación de igualdad falla.

Es una buena Java practicar siempre el uso de la primitiva clases de contenedor?Es obvio que iba a conseguir algunos bugs de la manera temprana, pero ¿cuáles son las desventajas de esto?Hace impacto en el rendimiento o la aplicación de la huella en la memoria?¿Hay algún furtivo trampas?

¿Fue útil?

Solución

El uso de la caja de tipos de ¿ tiene tanto rendimiento y problemas de memoria.

Al hacer comparaciones (por ejemplo, (i == 10) ), java tiene que unbox el tipo antes de hacer la comparación.Incluso el uso de i.equals(TEN) utiliza un método de llamada, que es más costoso y (OMI), más feo que el == sintaxis.

Volver a la memoria, el objeto tiene que ser almacenados en la pila (que también tiene un impacto en el rendimiento), así como de almacenar el valor en sí mismo.

Un truco de gotcha? i.equals(j) cuando i es null.

Yo siempre uso el primitivas, excepto cuando se puede ser null, pero siempre hay que consultar para null antes de comparación en esos casos.

Otros consejos

En primer lugar, el cambio de uso de una primitiva para el uso de un objeto sólo para obtener la capacidad para establecer en null es probablemente una mala decisión de diseño.A menudo tengo argumentos con mis compañeros de trabajo acerca de si es o no nulo es un valor de centinela, y mi opinión es que por lo general no es (y por lo tanto no debería ser prohibido como centinela de valores debe ser), pero en este caso en particular que va a salir de su manera de utilizarla como un valor de centinela.Por favor, no.Crear un valor booleano que indica si es o no su entero es válido, o crear un nuevo tipo que envuelve el booleano, entero juntos.

Generalmente, cuando el uso de las nuevas versiones de Java, me parece que no es necesario crear explícitamente o de fundición para el objeto versiones de primitivas debido a la auto-boxeo apoyo que se ha añadido algún tiempo en 1.5 (tal vez de 1,5 a sí mismo).

Me gustaría sugerir el uso de las primitivas de todo el tiempo a menos que usted realmente tiene el concepto de "null".

Sí, la máquina virtual no autoboxing y todos los que ahora, pero puede conducir a algo realmente extraño casos donde obtendrá una excepción de puntero nulo en una línea de código que usted realmente no espera, y usted tiene que empezar a hacer null comprueba en cada operación matemática.Usted también puede empezar a recibir a algunos no evidentes comportamientos si empiezan a mezclar los tipos y llegar extraño autoboxing comportamientos.

Para float/dobles puede tratar NaN como nulo, pero recuerde que NaN != NaN así que usted todavía necesita cheques especiales como !Flotador.isNaN(x).

Sería muy bueno si hubo colecciones que apoyaron a los tipos primitivos en lugar de tener que perder el tiempo/sobrecarga de boxeo.

En tu ejemplo, la declaración de si va a estar bien hasta que se vaya de más de 127 (as Integer autoboxing serán los valores de caché de hasta 127 y devolver la misma instancia para cada número de este valor)

Así es peor que usted lo presente...

if( i == 10 )

funciona como antes, pero

if( i == 128 )

va a fracasar.Es por razones como esta, que yo siempre explícitamente crear objetos cuando los necesito, y tienden a pegarse a las variables primitivas, si es posible

Te java POD tipos están ahí por una razón.Además de la sobrecarga, no se puede hacer normal de las operaciones con los objetos.Un Entero es un objeto, que deben ser asignados y la recolección.Un int no lo es.

Si este valor puede estar vacío, usted puede encontrar que en su diseño, usted está en necesidad de algo más.

Hay dos posibilidades: o bien el valor es sólo de datos (el código no actuar de manera diferente si se llena o no), o es en realidad lo que indica que tiene dos tipos diferentes de objetos de aquí (el código actúa de forma diferente si hay un valor de null)

Si sólo se trata de datos para visualización/almacenamiento, usted podría considerar el uso de un real DTO--uno que no lo tiene como un primer miembro de la clase en todo.Aquellos que por lo general tienen una forma de comprobar si se ha establecido un valor o no.

Si usted busca el valor null en algún momento, es posible que desee ser el uso de una subclase, porque cuando hay una diferencia, por lo general hay más.A menos que desee una mejor manera para indicar la diferencia de que "si primitiveIntValue == null", que en realidad no significa nada.

No cambie a no primitivas sólo para obtener este servicio.El uso de un valor booleano para indicar si el valor se establece o no.Si no te gusta esa solución y usted sabe que su enteros será en un plazo razonable (o no se preocupan por la falta ocasional) utilizar un valor específico para indicar 'sin inicializar', tales como número Entero.MIN_VALUE.Pero eso es mucho menos seguro de la solución de la booleano.

Cuando llegamos a ese 'más Tarde en punto, un poco más de trabajo necesarios para llevarse a cabo durante la refactorización.El uso de primitivas cuando sea posible.(Capital período), a Continuación, hacer POJOs si más funcionalidad es necesario.La primitiva clases contenedoras, en mi opinión, son los más utilizados por los datos que se necesita para viajar a través del cable, lo que significa red de aplicaciones.Permite valores nulos como valores aceptables causa dolores de cabeza como un sistema de 'crece'.A la cantidad de código que se desperdicia o pierde, guardando lo que debería ser simples comparaciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top