====== Conversiones de tipos primitivos ======
En Java, convertir directamente un tipo de datos a otro tipo se conoce como ''casting''.
Las conversiones entre tipos de datos solo se pueden hacer cuando los 2 tipos de datos involucrados, guardan una relación.
Esto ocurre solo con los tipos de datos numéricos y con los ''char''.
Existen dos tipos de conversiones:
* **Casting implícito**: se hacen de forma automática al asignar un tipo a otro, sin que hagamos nada.
* **Casting explícito**: debemos controlar e indicar nosotros la conversión.
==== Valores literales convertibles ====
|'b'| **char** |2 bytes|
|42|**int**|4 bytes|
|42L|**long**|8 bytes|
|22.3454F|**float**|4 bytes|
|22.3345|**double**|8 bytes|
**Los tipos** ''byte'' y ''short'' **no son muy usados en Java** por lo que no tienen repesentación literal. Simplemente se usa un valor literal ''int'' que cumpla el rango apropiado para el tipo.
===== Casting implícito =====
Automáticamente podemos asignar un valor literal o una variable de un tipo de dato, a otra variable de un tipo distinto, siempre convierta de un tipo a otro tipo más a la derecha, de los siguientes:
{{ :bloque2:casting_primitivos.png?600 |}}
Esto quiere decir que no necesitamos escribir ningún tipo de código para pasar de un tipo de datos a otro.
**Se da cuando "metemos" un valor pequeño en un contenedor (variable) más grande**.
//Ambos literales son literales de int, pero cumplen el rango de cada tipo
byte varPequena = 127;
short varGrande = 12365;
//Convierto de literal int a variable long
long enteroGrande = 24556;
//Convierto de tipo long a tipo float
float decimalSimple = enteroGrande;
//Convierto de float a double
double decimalDoble = decimalSimple;
//Convierto de literal float a double
decimalDouble = 3.14F;
===== Casting explícito =====
Se dan cuando intento asignar un tipo de datos más grande a una variable más pequeña.
El formato del casting es: (tipo)valorAConvertir;
(Donde el //tipo// es el tipo __al__ que se quiere convertir, y //valorAConvertir//, el valor desde el que se quiere convertir).
//una variable int ocupa 4 bytes, short 2 bytes
int entero = 13;
short enteroPequeno = (short)entero;
long numeroLargo = 13;
entero = (int)numeroLargo;
double decimal = 23423.234234;
entero = (int) decimal;
===== Casting caracter-entero =====
En algunos lenguajes de programación existe una relación entre los caracteres y los número enteros.
Los caracteres se codifican atendiendo al estandar [[ https://es.wikipedia.org/wiki/ISO/IEC_8859-1|ISO/IEC 8859-1]]. Los 128 primeros caracteres de esa tabla correponden con el estándar ASCII:
{{ :bloque2:codigo-ascii128.jpg?500 |}}
La codificación iso 8859-1 (latín), amplia ASCII con 128 caracteres usados en las lenguas occidentales:
{{ :bloque2:iso-8859-1.jpg?600 |}}
En dichas tablas existe una correspondencia entre el nº de orden del caracter y la representación literal del caracter.
Por lo tanto hay una serie de conversiones implícitas y explícitas que se permiten entre los tipos ''int'' y ''char'':
//Casting implícito
char letraA = 65; //valor ASCII -> 'A'
int valorA = letraA;
int valorB = 'B'; //entero ASCII -> 66
//Casting explícito
char letraB = (char)valorB; //convierto de int a char
===== Aspectos a tener en cuenta =====
Todas estas cuestiones están indicadas en la documentación sobre las [[ https://docs.oracle.com/javase/specs/jls/se8/html/index.html|especificaciones del lenguaje Java]].
* Cualquier operación aritmética entre **dos tipos de datos inferiores a ''int'' produce como resultado un ''int''**:
byte enteroByte = 4;
short enteroShort = 6;
short resultado = enteroByte + enteroShort; //Error
//Soluciones
short resultado = (short)(enteroByte + enteroShort);
int resultado = enteroByte + enteroShort;
* Cualquier operación aritmética entre dos tipos de datos distintos, produce como **resultado un tipo de datos igual al tipo mayor**:
long enteroLargo = 12;
int entero = 234;
entero * enteroLargo; // resultado tipo long
double decimal = 23.234;
entero - decimal; // resultado tipo double
* Siempre existe riesgo de pérdida de datos al hacer un **casting de un tipo más grande hacia un tipo más pequeño**:
int entero = 263;
El contenido de la variable ''entero'' (4 bytes) es:
''00000000-00000000-00000001-00000111''
Al hacer un casting a tipo ''byte'':
byte numero = (byte)entero;
La variable byte solo tiene 8 bits, por lo que solo se está guardando el último byte de la variable ''entero'':
''00000111'' cuyo valor es 7.
* Pérdida de precisión de tipos reales: Si intentamos **asignar un valor entero muy grande a este tipo de datos** (float o double), se realiza un casting implícito, pero hay riesgo de pérdida de datos.
===== Casting entre objetos =====
No puedo asignar directamente un objeto a una variable de otro tipo de objeto, a no ser que guarden una relación de herencia.
Tampoco puedo realizar un casting primitivo-objeto, a no ser mediante la relación primitivo -[[bloque3:wrappers | clase envoltorio de primitivo]].
----
(c) {{date> %Y}} Fernando Valdeón