Buscar
Social
Ofertas laborales ES
« Uso de paquetes en Java | Main | Diario de un principiante (Capítulo 3) »
sábado
sep012001

Conversrión de tipos en java


Conversión de tipos en Java.


Como en muchos otros lenguajes de programación, en Java también
es posible asignar un valor de un tipo a una variable de otro tipo. Es
muy probable que muchos de vosotros no le veáis a ésto mucha
ciencia o mucha dificultad pero también es verdad que muchos hacemos
la conversión automáticamente sin un cierto rigor que nos
respalde y cuando el compilador de Java nos da error seguimos intentándolo
por el método del "ensayo y error" ;-).

Pues para aquellos que aun no lo tienen claro o simplemente para tenerlo
todo recogido en este documento y no tener que ir a desempolvar aquel viejo
manual o libro con el que empezastes a hacer tus primeros pinitos en Java
aquí va este artículo. Además, esta es la sección
de los que empezamos en ésto del Java y la idea es allanar el terreno
en lo posible a todo aquél que comienza y afianzar ciertos conceptos
antes de pasar a cosas mayores.

Veamos a continuación, cómo hace la conversión
de tipos Java:



Conversión de tipos automática.


Si al hacer la conversión de un tipo a otro se dan las 2 siguientes
premisas:


  • Los dos tipos son compatibles.



  • El tipo de la variable destino es de un rango mayor al tipo de la variable
    que se va a convertir.


entonces, la conversión entre tipos es automática, ésto
es, la máquina virtual de Java tiene toda la información
necesaria para realizar la coversión sin necesidad de "ayuda" externa.
A ésto se le conoce como conversión implícita
y cuando hablamos de los tipos numéricos de Java se le da el nombre
de widening conversion que traducido vendría a ser algo así
como "conversión por ampliación". No obstante, no todos los tipos
numéricos son compatibles con char o boolean (concretamente byte y short) y estos dos no lo
son entre ellos.


Conversión de tipos incompatibles.


Cuando alguna de las 2 premisas anteriores no se cumple, entonces la conversión
automática es imposible (salvo que se esté evaluando una
expresión como se ve en el siguiente apartado), el compilador nos
da un error diciéndonos algo así como "la variable tal necesita
un cast explícito". Pero tranquilo, no es que no podamos realizar
tal conversión sino que la JVM necesita que le demos una información
adicional: el tipo al que vamos a convertir la variable fuente. Pues bien,
a esta conversión explícita es a lo que se le llama
hacer un casting de tipos. Cuando se trata de tipos numéricos
a este tipo de conversión se le llama narrowing compresion
que se podría traducir como "conversión por estrechamiento"
dado que estás "recortando" la variable para poderla meter en el
tipo destino.

La expresión general del casting de un tipo es:

(tipo_destino) valor

donde tipo_destino indica el tipo al que queremos hacer la conversión
explícita del valor asociado.

En el caso de los tipos numéricos, al "recortar" el valor de
la variable de rango mayor para que quepa en el tipo de rango menor resulta
que perdemos información. En el ejemplo verás en qué
se traduce esa pérdida de información según sean los
tipos.


Promoción de tipos automáticamente al evaluar una expresión.


Aquí radica a mi modo de ver uno de los puntos donde ésto
de la conversión nos puede dar la lata si no lo sabemos pero que
una vez sabido es una de las muchas ventajas que Java tiene frente a otros
lenguajes. El caso es que cuando la máquina virtual de Java tiene
que analizar una expresión existe la posibillidad  real de
que el resultado intermedio de una operación exceda el rango de
los operandos. Para solventar este problema lo que Java hace es una promoción
automática de todos los operandos de tipo byte o short a int. Pero
ésto también puede llevar al error de que hagamos una conversión
de tipos incompatibles y, al no hacer el casting correspondiente, la compilación
cascará. Mejor que explicarlo con letra lo vemos en el siguiente
ejemplo y verás que sencillo es recordarlo para no volver a meter
la pata.

Caso 1:

byte a = 40;
byte b = 50;
int c = a * b;//el compilador no dará ningún error.

Caso 2:
byte a = 25;
a = a*2; //ERROR: Explicit cast needed to convert int to byte.

Ahora te preguntarás, ¿cómo puede dar este error si
el resultado no excede del rango de un tipo byte (-128,127).

Pues bien, lo que ocurre es que al hacer la multiplicación,
Java ha promocionado automáticamente este valor a int y por eso
para volver a meterlo en un tipo byte tendremos que hacer una conversión
explícita. En el caso 1 este error no se produce porque el resultado
de la operación se guarda en un int.
a = (byte)a*2;//ahora el compilador no dará ningún error.

Para concluir con las reglas de promoción de tipos cuando evaluamos
expresiones aquí van otros detalles más que hay que tener
en cuenta:


  • Si alguno de los operandos es long, entonces la expresión entera
    promociona a long.



  • Si alguno de los operandos es float, entonces la expresión entera
    promociona a float.



  • Si alguno de los operandos es double, entonces el resultado será
    double.


Por último, recuerda que cuando un método nos devuelve Object,
dado que esta clase es la super-clase de todas, entonces podremos y tenemos
que hacer un casting explícito al tipo de la variable que nos interesa.
Por ejemplo, si tenemos un vector en el que vamos introduciendo elementos
del tipo MiClase, para poderlos recuperar habría que hacer:


Miclase var = (MiClase) vector.get(index);
//get devuelve Object y hacemos el cast a MiClase para que los tipos sean compatibles.



El ejemplo.


Bueno, tampoco es que sea un ejemplo, simplemente son una serie de casos
prácticos para concluir este artículo.

class ConversionTipos {
public static void main(String args[]) {
byte b;
int i = 257;
double d = 323.142;
double d2;
float f = 5.65f;
char c = 'c';
short s = 1024;

b = (byte) i;//efecto: se devuelve (i modulo 256), rango de byte.
System.out.println(b);
i = (int) d;//efecto: truncamiento de la parte decimal.
System.out.println(i);
b = (byte)d;//efecto: truncamiento y luego (result_truncado modulo 256)
System.out.println(b);
i = (int)f;//efecto: truncamiento de la parte decimal
System.out.println(i);
i = c;//correcto por ser int, pero un byte o short necesitaría un cast explícito.
System.out.println(i);
f = c; d = c;//correcto.
i = b * c;//efecto: la operación promociona a int.
System.out.println(i);
d2 = (f*b) + (i/c) - (d*s);
/*
efecto: el resultado de la promoción de todas las expresiones es un double:
(f*b) promociona a float, (i/c) promociona a int y (d*s) promociona a double. Luego,
float + int - double promociona a double.
*/
System.out.println(d2);
}
}















Leo Suarez es un Ingeniero Superior de Telecomunicaciones por la
Universidad de Las Palmas de Gran Canaria con todas sus letras, que no
son pocas, y trabaja como tal en Santa Cruz de Tenerife.
Cuando no
está saltando de isla en isla o escribiendo para javaHispano aprovecha
para disfrutar con la novia y los amigos del estupendo clima de las islas afortunadas.

Para cualquier duda o tirón de orejas, e-mail a:
leo_ARROBA_javahispano.com




Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.
Comentarios deshabilitados
Comentarios deshabilitados en esta noticia.