Java es un lenguaje fuertemente tipado, pero aún es posible transferir valores entre variables primitivas de diferentes tipos. Por ejemplo, puedo asignar el valor de un int a un double sin ningún problema, siempre que la capacidad de almacenamiento del tipo que recibe el valor pueda soportarlo.
Vea a continuación el tamaño de cada tipo primitivo:
Transferir valor a un tipo con mayor capacidad de almacenamiento tiene un nombre técnico: "conversión ampliada". El término en portugués suele traducirse como "conversión de ampliación" o "conversión de ampliación". Se refiere al proceso en el que un valor de un tipo de datos más pequeño o más restringido se convierte a un tipo más grande o más completo sin pérdida de información.
Pero ¿qué pasa si quiero transferir el valor a un tipo con menos capacidad de almacenamiento? Al compilador de Java no le gusta esto, pero lo permitirá si lo convierte, como en el siguiente ejemplo.
double decimal = 65.9; int i = (int) decimal; //aqui ele perde a casa decimal e vira 65 char c = (char) i; //aqui ele vira a letra A (que corresponde a 65)
Si el tamaño del valor que irá al nuevo tipo excede los límites de ese tipo, puede suceder algo más dramático. Un int i = 10 cabe en una variable de byte, ya que contiene 8 bits en un rango de -128 a 127. Sin embargo, ¿qué pasa si quiero poner un int i = 128 en una variable de tipo byte... habrá una pérdida de información.
public class Main { public static void main(String[] args) { int i = 128; byte b = (byte) i; System.out.println(b); // o valor de b agora é -128 :S } }
En el último post [léelo aquí], hablé un poco sobre las clases Wrapper. Como ejemplo, había escrito Integer.parse(i) = imagina que i es un tipo
int primitivo.
Actualmente, ya no se recomienda el uso del método de análisis Wrapper, ya que está en desuso. Para transformar una primitiva en una clase Wrapper y, de esta manera, utilizar métodos integrados, se recomienda hacer "autoboxing", como en el ejemplo:
Character ch = 'a'; Integer i = 10;
Tenga en cuenta que este es un enfoque más directo. Simplemente asigna el valor de una vez.
Para hacer lo contrario y devolver los datos como un tipo primitivo, puedes hacer el "unboxing" usando el método valueOf:
Integer i = 10; int j = Integer.valueOf(i);
Hacer el Wrapper de una primitiva, como dije en el post anterior, tiene la ventaja de permitirte utilizar los métodos de la clase y hacerte la vida más fácil a la hora de trabajar con los datos.
La versión contenedora de una primitiva puede parecerse mucho a primera vista, pero la JVM no trata un objeto y una primitiva de la misma manera, no lo olvides. Recuerde que las primitivas van al Stack y los objetos al Heap [recuerde aquí].
En términos de rendimiento, está claro que recuperar datos de una primitiva es menos costoso para la computadora, ya que el valor se almacena directamente y no por referencia. Es mucho más rápido obtener datos ya preparados que seguir juntando las piezas en la memoria.
Pero hay casos en los que usar un Wrapper será esencial. Por ejemplo, cuando quieres trabajar con la clase ArrayList. Solo acepta objetos como parámetros, no valores primitivos.
La flexibilidad que aporta esta transformación de primitivo a objeto y viceversa es realmente genial en el lenguaje. Pero debemos ser conscientes de estos escollos que se analizan aquí y de muchos otros.
Solo para sorprender a la sociedad (risas), voy a dar un ejemplo de un caso problemático que involucra el comportamiento inesperado de un código cuando se trabaja con sobrecarga (todavía no he hecho una publicación sobre sobrecarga, pero lo haré. Básicamente, la sobrecarga ocurre cuando un método tiene firmas diferentes).
Este caso fue mencionado en el libro "Effective Java", de Joshua Bloch.
public class SetListTest { public static void main(String[] args) { Setset = new TreeSet(); List list = new ArrayList(); for (int i = -3; i En este programa, el objetivo era sumar valores enteros de -3 a 2 [-3, -2, -1, 0, 1, 2] a un conjunto y una lista. Luego elimine los valores positivos [0, 1 y 2]. Pero, si ejecuta este código, notará que el conjunto y la lista no presentaron el mismo resultado. El conjunto devuelve [-3, -2, -1], como se esperaba. La lista devuelve [-2, 0, 2].
Esto sucede porque la llamada al método incorporado remove(i) de la clase List trata a i como un tipo primitivo int, y nada más. El método, a su vez, elimina elementos en la posición i.
La llamada al método remove(i) de la clase Set llama a una sobrecarga que recibe un objeto Integer como parámetro, convirtiendo automáticamente i, que originalmente era un int, a Integer. El comportamiento de este método, a su vez, excluye del conjunto los elementos que tienen un valor igual a i (y no un índice igual a i); tenga en cuenta que el tipo esperado tanto para el conjunto como para la lista era Entero. (Establecer conjunto / Lista de lista). Es por eso que la sobrecarga elegida para el método remove, de la clase Set, lo convirtió a Integer.
Si bien el comportamiento de eliminar en Lista es eliminar por índice, eliminar en Conjunto es eliminar por valor. Todo debido a la sobrecarga de remove que recibe Integer.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3