1. Encasillamiento

Encasillamiento en Java

Las variables de tipos primitivos (con la excepción del booleantipo) se utilizan para almacenar varios tipos de números. Aunque los tipos de variables nunca cambiaron, hay un lugar donde puede convertir de un tipo a otro. Y ese lugar es la asignación .

Las variables de diferentes tipos se pueden asignar entre sí. Cuando hace esto, el valor de una variable de un tipo se convierte en un valor de otro tipo y se asigna a la segunda variable. En este sentido, podemos identificar dos tipos de conversión de tipo: ampliación y reducción.

Ampliar es como mover un valor de una canasta pequeña a una grande: esta operación es perfecta e indolora. La reducción ocurre cuando mueve un valor de una cesta grande a una pequeña: puede que no haya suficiente espacio y tendrá que tirar algo.

Estos son los tipos, ordenados por tamaño de cesta:

Encasillamiento en Java 2


2. Ampliación de conversiones de tipo

A menudo es necesario asignar una variable de un tipo numérico a una variable de otro tipo numérico. ¿Cómo haces eso?

Java tiene 4 tipos de enteros:

Tipo Tamaño
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

Las variables almacenadas en cestas más pequeñas siempre se pueden asignar a las variables almacenadas en cestas más grandes.

int, shorty bytelas variables se pueden asignar fácilmente a longlas variables. shorty bytelas variables se pueden asignar a intlas variables. Y bytelas variables se pueden asignar a shortlas variables.

Ejemplos:

Código Descripción
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
Este código compilará muy bien.

Tal conversión, de un tipo más pequeño a uno más grande, se denomina conversión de tipo de ampliación .

¿Qué pasa con los números reales?

Con ellos, todo es igual, el tamaño importa:

Tipo Tamaño
float 4 bytes
double 8 bytes

floatlas variables se pueden asignar a doublelas variables sin ningún problema. Pero las cosas son más interesantes con los tipos enteros.

Puede asignar cualquier variable entera a una floatvariable. Incluso el longtipo, que tiene una longitud de 8 bytes. Y puede asignar lo que quiera, cualquier variable entera o floatvariable, a una doublevariable:

Código Nota
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

Tenga en cuenta que la conversión a un tipo real puede provocar una pérdida de precisión debido a la falta de suficientes dígitos significativos.

Al convertir números enteros a números de coma flotante, las partes de orden inferior de los números pueden descartarse. Pero dado que se entiende que los números fraccionarios almacenan valores aproximados, tales operaciones de asignación están permitidas.


3. Conversiones de tipo de restricción

¿Qué pasa con las otras posibilidades? ¿ Qué sucede si necesita asignar un longvalor a una intvariable?

Imagina una variable como una canasta. Disponemos de cestas de varios tamaños: 1, 2, 4 y 8 bytes. No es un problema transferir manzanas de una canasta más pequeña a una más grande. Pero al pasar de una canasta más grande a una más pequeña, es posible que se pierdan algunas de las manzanas.

Esta transformación, de un tipo más grande a un tipo más pequeño, se denomina conversión de tipo de reducción . Al realizar una operación de asignación como esta, es posible que parte de un número simplemente no encaje en la nueva variable y, por lo tanto, se descarte.

Al restringir un tipo, debemos decirle explícitamente al compilador que no estamos cometiendo un error, que estamos descartando deliberadamente parte del número. El operador typecast se utiliza para esto. Es un nombre de tipo entre paréntesis .

En tales situaciones, el compilador de Java requiere que el programador especifique el operador typecast. En general, se ve así:

(type) expression

Ejemplos:

Código Descripción
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
Cada vez que el operador encasillado debe indicarse explícitamente

Aquí aes igual a 1, y quizás el operador de encasillamiento parezca una exageración. Pero, ¿y si afuera más grande?

Código Descripción
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

Un millón encaja perfectamente en un longy en un int. Pero cuando se asigna un millón a una shortvariable, los primeros dos bytes se descartan y solo se retienen los dos últimos bytes. Y al asignar a un byte, lo único que queda es el último byte.

Cómo se ordenan los números en la memoria:

Tipo notación binaria Notación decimal
int 0b 00000000 00001111 01000010 01000000 1000000
short 0b 01000010 01000000 16.960
byte 0b 01000000 64

chartipo

A char, como a short, ocupa dos bytes, pero para convertir uno a otro, siempre necesita usar un operador typecast. El problema aquí es que el shorttipo está firmado y puede contener valores desde -32,768hasta +32,767, pero el chartipo no está firmado y puede contener valores desde 0hasta 65,535.

Los números negativos no se pueden almacenar en un char, pero se pueden almacenar en un short. Y a shortno puede almacenar números mayores que 32,767, pero tales números pueden almacenarse en a char.


4. Tipo de expresión

¿Qué sucede si se utilizan variables de diferentes tipos en la misma expresión? Lógicamente, entendemos que primero deben convertirse a un tipo común. ¿Pero cual?

Al más grande, por supuesto.

Java siempre convierte al tipo más grande. En términos generales, primero se amplía uno del tipo y solo entonces se realiza la operación utilizando valores del mismo tipo.

Si an inty a longestán involucrados en una expresión, el valor de se intconvertirá en a longy solo entonces procederá la operación:

Código Descripción
int a = 1;
long b = 2;
long c = a + b;
ase ampliará a a longy luego se producirá la adición.

Números de punto flotante

Si un número entero y un número de punto flotante ( floato double) están involucrados en una expresión, el número entero se convertirá en un número de punto flotante ( floato double), y solo entonces se realizará la operación.

Si la operación involucra a floaty a double, entonces se floatconvertirá en a double. Lo que en realidad se espera.

Sorpresa

Los tipos byte, shorty charsiempre se convierten intcuando interactúan entre sí. Hay una buena razón por la que el inttipo se considera el tipo entero estándar.

Si multiplicas a bytepor a short, obtienes un int. Si multiplicas a bytepor a byte, obtienes un int. Incluso si sumas a bytey a byte, obtienes un int.

Hay varias razones para esto. Ejemplos:

Código Descripción
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 120is 13,200, que es ligeramente mayor que el valor máximo del bytetipo:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120is 230, que también es ligeramente mayor que el valor máximo del bytetipo:127

En general, al multiplicar un número de 8 bits (1 byte) por un número de 8 bits (1 byte), obtenemos un número que ocupa 16 bits bits (2 bytes)

Como resultado, todas las operaciones con tipos enteros menores que intsiempre se convierten inmediatamente a ints. Y eso significa que si desea almacenar el resultado del cálculo en una variable de un tipo que es más pequeño que un int, siempre deberá especificar explícitamente el operador de encasillamiento.

Ejemplos:

Código Descripción
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
La byte * byteexpresión será unint
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
La byte + byteexpresión será unint
byte a = 1;
byte b = (byte) (a + 1);
La byte + intexpresión será un int
El literal es un int.

5. Un matiz importante

El operador typecast tiene una prioridad bastante alta.

Eso significa que si una expresión contiene, por ejemplo, una suma y un operador de encasillado, el encasillado se realizará antes que la suma.

Ejemplo:

Código Descripción
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
El operador typecast solo se aplicará a la avariable, que ya es un byte. Este código no se compilará.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
Esta es la forma correcta.

Si desea convertir la expresión completa a un tipo específico, y no solo un componente de la expresión, envuelva la expresión completa entre paréntesis y coloque el operador de conversión de tipos al frente.