Rzutowanie typów niezgodnych w JAVA
Chociaż automatyczne konwersje są pomocnym mechanizmem, często okazują się niewystarczające, ponieważ są stosowane jedynie do typów zgodnych przy założeniu szerszej reprezentacji typu docelowego. W innych sytuacjach konieczne staje się użycie rzutowania. Rzutowanie stanowi instrukcję dla kompilatora, aby przekształcił jeden typ w drugi. Innymi słowy, rzutowanie jest jawnym żądaniem konwersji. Ma ono następującą postać ogólną:
(typ-docelowy) wyrażenie
typ-docelowy określa typ, do którego należy przekształcić wyrażenie. Na przykład: jeśli zechcesz przekształcić wyrażenie x/y od typu int, możesz napisać:
// ...
(int) (x / y)
Chociaż obie zmienne x i y są typu double, rzutowanie przekształca wynik ich dzielenia do typu int. Nawiasy obejmujące wyrażenie x/y są konieczne. W przeciwnym wypadku rzutowanie na typ int zostałoby zastosowane tylko do zmiennej x zamiast do wyniku dzielenia. Zastosowanie rzutowania jest konieczne, ponieważ automatyczna konwersja typu double do typu int nie jest możliwa.
Jeśli reprezentacja typu docelowego nie jest wystarczająco pojemna, podczas konwersji może dojść do utraty informacji. Na przykład podczas rzutowania typu long na short informacja zostanie utracona, jeśli wartość typu long jest większa niż zakres typu short, ponieważ podczas konwersji zostaną usunięte bardziej znaczące bity reprezentacji typu long. Podczas rzutowania wartości zmiennoprzecinkowej na typ całkowity zostanie obcięta część dziesiętna. Na przykład przypisanie wartości 1.23 zmiennej całkowitej da w wyniku wartość 1. Część dziesiętna równa 0.23 zostanie utracona.
Program przedstawiony na listingu 2.17 demonstruje niektóre typy konwersji wymagające rzutowania.
Listing 2.17. CastDemo.java
class CastDemo {
public static void main(String args[]) {
double x, y;
byte b;
int i;
char ch;
x = 10.0;
y = 3.0;
// Rzutowanie obetnie część dziesiętną wyniku.
i = (int) (x / y); // rzutuje double na int
System.out.println("Całkowity wynik dzielenia x / y: " + i);
i = 100;
b = (byte) i; // Brak utraty informacji: byte umożliwia reprezentację wartości 100.
System.out.println("Wartość zmiennej b: " + b);
i = 257;
b = (byte) i; Utrata informacji: byte nie umożliwia reprezentacji wartości 257.
System.out.println("Wartość zmiennej b: " + b);
b = 88; // kod ASCII litery X
ch = (char) b; Rzutowanie typu niezgodnego.
System.out.println("ch: " + ch);
}
}
Wynik działania programu przedstawiłem poniżej.
Wartość zmiennej b: 100
Wartość zmiennej b: 1
ch: X
W tym programie rzutowanie wyrażenia (x/y) na typ int powoduje obcięcie części dziesiętnej wyniku. Utrata informacji nie występuje natomiast w przypadku przypisania zmiennej b wartości 100, ponieważ należy ona do zakresu reprezentowanego przez typ byte. Jednak już przypisanie zmiennej b wartości 257 wiąże się z utratą informacji, ponieważ wartość jest większa od maksymalnej wartości reprezentowanej przez typ byte. Przypisanie wartości typu byte zmiennej typu char nie wiąże się z utratą informacji, ale wymaga zastosowania rzutowania.
Java. Przewodnik dla początkujących. Wydanie VI, Autor: Herbert Schildt, Wydawnictwo: Helion