1. Encasillamiento
Las variables de tipos primitivos (con la excepción del boolean
tipo) 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:
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
, short
y byte
las variables se pueden asignar fácilmente a long
las variables. short
y byte
las variables se pueden asignar a int
las variables. Y byte
las variables se pueden asignar a short
las variables.
Ejemplos:
Código | Descripción |
---|---|
|
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 |
float
las variables se pueden asignar a double
las variables sin ningún problema. Pero las cosas son más interesantes con los tipos enteros.
Puede asignar cualquier variable entera a una float
variable. Incluso el long
tipo, que tiene una longitud de 8 bytes. Y puede asignar lo que quiera, cualquier variable entera o float
variable, a una double
variable:
Código | Nota |
---|---|
|
|
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 long
valor a una int
variable?
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 |
---|---|
|
Cada vez que el operador encasillado debe indicarse explícitamente |
Aquí a
es igual a 1
, y quizás el operador de encasillamiento parezca una exageración. Pero, ¿y si a
fuera más grande?
Código | Descripción |
---|---|
|
|
Un millón encaja perfectamente en un long
y en un int
. Pero cuando se asigna un millón a una short
variable, 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 |
char
tipo
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 short
tipo está firmado y puede contener valores desde -32,768
hasta +32,767
, pero el char
tipo no está firmado y puede contener valores desde 0
hasta 65,535
.
Los números negativos no se pueden almacenar en un char
, pero se pueden almacenar en un short
. Y a short
no 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 int
y a long
están involucrados en una expresión, el valor de se int
convertirá en a long
y solo entonces procederá la operación:
Código | Descripción |
---|---|
|
a se ampliará a a long y luego se producirá la adición. |
Números de punto flotante
Si un número entero y un número de punto flotante ( float
o double
) están involucrados en una expresión, el número entero se convertirá en un número de punto flotante ( float
o double
), y solo entonces se realizará la operación.
Si la operación involucra a float
y a double
, entonces se float
convertirá en a double
. Lo que en realidad se espera.
Los tipos byte
, short
y char
siempre se convierten int
cuando interactúan entre sí. Hay una buena razón por la que el int
tipo se considera el tipo entero estándar.
Si multiplicas a byte
por a short
, obtienes un int
. Si multiplicas a byte
por a byte
, obtienes un int
. Incluso si sumas a byte
y a byte
, obtienes un int
.
Hay varias razones para esto. Ejemplos:
Código | Descripción |
---|---|
|
110 * 120 is 13,200 , que es ligeramente mayor que el valor máximo del byte tipo:127 |
|
110 + 120 is 230 , que también es ligeramente mayor que el valor máximo del byte tipo: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 int
siempre se convierten inmediatamente a int
s. 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 |
---|---|
|
La byte * byte expresión será unint |
|
La byte + byte expresión será unint |
|
La byte + int expresió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 |
---|---|
|
El operador typecast solo se aplicará a la a variable, que ya es un byte . Este código no se compilará. |
|
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.
GO TO FULL VERSION