¿Cuándo usar primitiva vs clase en Java?

44

Veo que Java tiene Boolean (clase) vs booleano (primitivo). Del mismo modo, hay un entero (clase) vs int (primitivo). ¿Cuál es la mejor práctica sobre cuándo usar la versión primitiva frente a la clase? ¿Básicamente, siempre debería usar la versión de clase a menos que tenga una razón específica (rendimiento) para no hacerlo? ¿Cuál es la forma más común y aceptada de usar cada uno?

    
pregunta Casey Patton 07.07.2013 - 10:15

5 respuestas

40

En el artículo 5, de Java efectiva, Joshua Bloch dice

  

La lección está clara: preferiremos los primitivos a   primitivas en caja, y ten cuidado con el autoboxing involuntario .

Un buen uso para las clases es cuando se usan como tipos genéricos (incluidas las clases de Colección, como listas y mapas) o cuando se quieren transformar a otro tipo sin conversión implícita (por ejemplo, la clase Integer tiene métodos doubleValue() o byteValue() .

Edit: la razón de Joshua Bloch es:

// Hideously slow program! Can you spot the object creation?
public static void main(String[] args) {
    Long sum = 0L;
    for (long i = 0; i < Integer.MAX_VALUE; i++) {
         sum += i;
    }
    System.out.println(sum);
}
     

Este programa obtiene la respuesta correcta, pero es mucho más lento de lo que debería ser,   Debido a un error tipográfico de un carácter. La variable sum se declara como Long en lugar de long , lo que significa que el programa construye aproximadamente 2 ^ 31 instancias Long innecesarias (aproximadamente una por cada vez que se agrega long i a Long sum ). Cambiar la declaración de suma de Long a long reduce el tiempo de ejecución de 43 segundos a 6,8 segundos en mi máquina.

    
respondido por el m3th0dman 07.07.2013 - 10:47
26

La práctica estándar es ir con los primitivos, a menos que se trate de genéricos (asegúrese de conocer autoboxing & unboxing !).

Hay varias buenas razones para seguir la convención:

1. Evitas errores simples:

Hay algunos casos sutiles, no intuitivos, que a menudo atrapan a los principiantes. Incluso los programadores experimentados se equivocan y cometen estos errores a veces (¡espero que esto sea seguido por una maldición cuando depuren el código y encuentren el error!).

El error más común es usar a == b en lugar de a.equals(b) . La gente está acostumbrada a hacer a == b con primitivos, por lo que es fácil hacerlo cuando estás usando las envolturas de objetos.

Integer a = new Integer(2);
Integer b = new Integer(2);
if (a == b) { // Should be a.equals(b)
    // This never gets executed.
}
Integer c = Integer.valueOf(2);
Integer d = Integer.valueOf(2);
if (c == d) { // Should be a.equals(b), but happens to work with these particular values!
    // This will get executed
}
Integer e = 1000;
Integer f = 1000;
if (e == f) { // Should be a.equals(b)
    // Whether this gets executed depends on which compiler you use!
}

2. Legibilidad:

Considere los siguientes dos ejemplos. La mayoría de la gente diría que el segundo es más legible.

Integer a = 2;
Integer b = 2;
if (!a.equals(b)) {
    // ...
}
int c = 2;
int d = 2;
if (c != d) {
    // ...
}

3. Rendimiento:

El hecho es que es más lento usar los Envoltorios de Objetos para primitivos que solo usar los primitivos. Está agregando el costo de la creación de instancias de objetos, las llamadas a métodos, etc. a las cosas que usa en todo el lugar .

Knuth's "... por ejemplo, aproximadamente el 97% del tiempo: la optimización prematura es la raíz de todo mal". La cita no se aplica aquí. Hablaba de optimizaciones que hacen que el código (o el sistema) sea más complicado. Si está de acuerdo con el punto 2, esta es una optimización que hace que el código sea menos complicado.

4. Es la convención:

Si realiza diferentes elecciones estilísticas al 99% de los otros programadores de Java, existen 2 desventajas:

  • Encontrará el código de otras personas más difícil de leer. El 99% de los ejemplos / tutoriales / etc por ahí usarán primitivos. Cada vez que lea uno, tendrá la sobrecarga cognitiva adicional de pensar cómo se vería en el estilo al que está acostumbrado.
  • Otras personas encontrarán tu código más difícil de leer. Cada vez que haga preguntas sobre el desbordamiento de pila, tendrá que analizar las respuestas / comentarios preguntando "¿por qué no usa primitivos?". Si no me crees, solo observa las batallas que tiene la gente sobre cosas como la colocación de corchetes, ¡lo que ni siquiera afecta el código generado!

Normalmente, enumero algunos puntos clave, ¡pero honestamente no puedo encontrar ninguna buena razón para no asistir a la convención aquí!

    
respondido por el vaughandroid 08.07.2013 - 16:31
12

Por lo general voy con los primitivos. Sin embargo, una peculiaridad de usar clases como Integer y Boolean es la posibilidad de asignar null a esas variables. Por supuesto, esto significa que tiene que hacer null cheques todo el tiempo, pero aún así es mejor obtener una NullPointerException que tener errores lógicos debido al uso de alguna variable int o boolean que no se ha inicializado correctamente.

Además, introduce la posibilidad de utilizar null para asignar a esas variables un valor " desconocido " o " comodín ". Esto puede ser útil en algunas situaciones, por ejemplo, en Lógica Ternaria . O es posible que desee comprobar si un determinado objeto coincide con alguna plantilla; en este caso, puede usar null para aquellas variables en la plantilla que pueden tener cualquier valor en el objeto.

    
respondido por el tobias_k 07.07.2013 - 11:23
2

En palabras sencillas:

Utiliza los contenedores cuando necesitas agregar elementos a las colecciones.

Las colecciones no pueden contener primitivas.

    
respondido por el Tulains Córdova 08.07.2013 - 16:17
0

Java cuenta con el autoboxing como m3th0dman señaló. Piense en el nivel más bajo posible y verá que el cambio automático (dentro o fuera) un valor primitivo implicará ciclos de reloj empleados en algunas tareas que no necesita si trabaja con tipos de datos nativos en su aplicación.

Como regla general, debes intentar usar tipos de datos nativos siempre que sea posible.

    
respondido por el Silvarion 08.07.2013 - 16:20

Lea otras preguntas en las etiquetas