objeto - Cuándo usar primitivos y cuándo tipos de referencia en Java.
tipos de variables en java netbeans (10)
¿En qué caso debería usar tipos primitivos (
int
) o tipos de referencia (Integer
)?
Como regla general, usaré una primitiva (como int
) a menos que tenga que usar una clase que envuelva una primitiva.
Uno de los casos en los que se debe usar una clase de envoltorio como Integer
es en el caso de usar generics , ya que Java no admite el uso de tipos primitivos como parámetros de tipo:
List<int> intList = new ArrayList<int>(); // Not allowed.
List<Integer> integerList = new ArrayList<Integer>(); // Allowed.
Y, en muchos casos, aprovecharé el autoboxing y el desempaquetado , por lo que no tengo que realizar explícitamente las conversiones de los primitivos a su clase de contenedor y viceversa:
// Autoboxing will turn "1", "2", "3" into Integers from ints.
List<Integer> numbers = Arrays.asList(1, 2, 3);
int sum = 0;
// Integers from the "numbers" List is unboxed into ints.
for (int number : numbers) {
sum += number;
}
Además, como nota adicional, al convertir de primitivos a sus objetos de clase envoltura y no son necesarias instancias únicas de objetos, use el método valueOf
proporcionado por el método envoltorio, ya que realiza el almacenamiento en caché y devuelve la misma instancia para un determinado valor. Reduciendo el número de objetos que se crean:
Integer i1 = Integer.valueOf(1); // Prefer this.
Integer i2 = new Integer(1); // Avoid if not necessary.
Para obtener más información sobre los métodos valueOf
, la especificación de la API para el método Integer.valueOf
puede servir como referencia sobre cómo se comportarán esos métodos en las clases de envoltorio para primitivas.
¿En qué caso debería usar tipos primitivos ( int
) o tipos de referencia ( Integer
)?
Esta question despertó mi curiosidad.
Creo que es un poco tarde, pero quería agregar mi opinión por si acaso.
en algunos escenarios, se requiere usar los envoltorios ya que la falta de un valor es diferente del valor predeterminado.
por ejemplo, para un proyecto en el que trabajé, había un campo en la pantalla donde el usuario podía ingresar un valor doble, el requisito comercial se mencionaba claramente que si el usuario ingresa un 0, el significado es diferente de no ingresar un valor y dejar el campo en blanco y esta diferencia tendrá un impacto más adelante en un módulo diferente. así que en este escenario tuvimos que usar el objeto Doble, ya que no puedo representar una falta de valor usando la primitiva; ya que la primitiva se establecerá por defecto en 0, lo que fue una entrada válida para el campo.
En lugar de llamarlos "tipos complejos", sería mejor que te sirvan el pensamiento Integer, Double, etc. como "Classes", e int, double, etc. como "primitivos".
Si está haciendo cualquier tipo de matemática sofisticada, la representación numérica basada en clase como Integer y Double será incómoda y lenta, muchas operaciones matemáticas solo pueden hacerse con primitivos.
Por otro lado, si está tratando de poner sus números en colecciones como Listas y Mapas, esas colecciones solo pueden contener objetos y, por lo tanto, debe usar (o convertir) clases como Integer y Double.
Personalmente, uso primitivas siempre que puedo salirme con la miya, y solo me convierto a las representaciones de clase como Integer cuando es el momento de hacer una entrada o salida, y el transporte requiere esas representaciones.
Sin embargo, si no está haciendo ningún cálculo matemático y, en cambio, simplemente está pasando los valores directamente a través de su código, puede ahorrar algunos problemas al tratar con los formularios basados en la Clase (como Integer) exclusivamente.
Eso realmente depende del contexto. Primero prefiera el primitivo, porque es más intuitivo y tiene menos gastos generales. Si no es posible por motivos genéricos / autoboxing, o si desea que sea anulable, vaya al tipo de envoltorio (tipo complejo como lo llama).
Las reglas generales que sigo al crear una API se pueden resumir de la siguiente manera:
- Si el método debe devolver un valor, use un tipo primitivo
- Si es posible que el método no siempre se aplique (por ejemplo: getRadioId (...) en un objeto donde tal ID no exista), devuelva un entero y especifique en los JavaDocs que el método devolverá el valor nulo en algunos casos.
En el # 2, busque NPE cuando realice un autoboxing. Si tienes un método definido como:
public Integer getValue();
Y luego llámalo como sigue:
int myValue = getValue();
En el caso de que getValue () devuelva nulo, obtendrá una NPE sin una causa obvia.
Mi regla de oro es: usar primitivos en caja solo cuando sea necesario para compilar el código. Los únicos lugares en su código donde deben aparecer los nombres de las clases primitivas de envoltorio son los parámetros de tipo genérico y las llamadas a métodos estáticos:
List<Integer> intList = new ArrayList<Integer>();
int n = Integer.parseInt("123");
Ese es el consejo que daría a los nuevos programadores de Java. A medida que aprendan más, se encontrarán con situaciones en las que deben ser más exigentes, como cuando tratan con mapas o bases de datos, pero para entonces también deberían tener una mejor comprensión de la diferencia entre los primitivos y los primitivos en caja.
Autoboxing nos tienta a creer que int
y Integer
(por ejemplo) son intercambiables, pero es una trampa. Si mezcla los dos tipos de valores de forma indiscriminada, puede terminar comparando dos valores de Enteros con ==
o intentando desempaquetar un null
sin darse cuenta. Los errores resultantes pueden ser intermitentes y difíciles de localizar.
No ayuda que comparar primitivos en caja con ==
veces funcione como si estuviera haciendo una comparación de valores. Es una ilusión causada por el hecho de que los valores dentro de un cierto rango se almacenan automáticamente en caché en el proceso de autoboxing. Es el mismo problema que siempre hemos tenido con los valores de String: compararlos con ==
veces "funciona" porque en realidad estás comparando dos referencias con el mismo objeto almacenado en caché.
Cuando se trata de cadenas, podemos decirle a la n00bs que nunca las compare con ==
, como lo hemos estado haciendo todo el tiempo. Pero comparar primitivas con ==
es perfectamente válido; El truco (gracias al autoboxing) es asegurarse de que los valores sean realmente primitivos. El compilador ahora nos permitirá declarar una variable como un Integer
y usarla como si fuera un int
; eso significa que tenemos que ejercer un mayor nivel de disciplina y tratarlo como un error cuando alguien lo hace sin una buena razón.
No creo que haya ninguna regla como tal. Elegiría los tipos sobre primitivos (Integer sobre int) cuando escribo firmas de métodos, mapas, colecciones, objetos de datos que se transmiten. Como tal, todavía me gustaría usar Integer en lugar de int incluso dentro de los métodos, etc. Pero si piensa que es demasiado problema (escribir "eger" extra), está bien usar ints para las variables locales.
Si desea establecer Atributo a sesión, tiene que usar Objeto como Integer, Boolean, String en servlets. Si quieres usar valor puedes usar tipos primitivos. Los objetos pueden ser nulos pero los primitivos no. Y si desea comparar tipos para primitivos, use == pero los objetos usan .equals porque en la comparación de objetos == no se ven los valores si estos son los mismos objetos. Y el uso de primitivas hace más rápido el código.
Un caso en el que podría preferirse Integer
es cuando se trabaja con una base de datos donde se permite que las entradas numéricas sean nulas, ya que no podría representar un valor nulo con un int
.
Pero, por supuesto, si estás haciendo cálculos matemáticos directos, entonces sería mejor como lo han mencionado otros debido a la intuición y menos gastos generales.
Ya que Java hace algo llamado auto-boxing y auto-unboxing , debe usar el tipo primitivo int
en la mayoría de los casos debido a una menor sobrecarga.
La única vez que absolutamente necesita usar Integer es en genéricos.
List<int> list; // won''t compile
List<Integer> list; // correct