Zagadki Java zawierają różnego rodzaju niuanse języka i „podchwytliwe” fragmenty kodu. Każda następna zagadka będzie zawierała odpowiedź i wyjaśnienie do poprzedniej. Lista wszystkich zagadek.
Jeżeli znasz odpowiedź, podziel się nią w komentarzu!
Zagadka Java #2¶
Jaki będzie wynik kompilacji i uruchomienia klasy Cat?
public class Cat extends Animal { public static void makeSound() { System.out.println("♪ Meow. ♪"); } public static void main(String[] args) { Animal animal = new Cat(); animal.makeSound(); } }
Klasa bazowa wygląda następująco:
public class Animal { public static void makeSound() { System.out.println("♪ Generic animal sound. ♪"); } }
Odpowiedź do poprzedniej zagadki #1¶
Poniżej znajdziesz odpowiedź do poprzedniej zagadki.
Kompilacja pierwszej klasy, AssignmentOperator, kończy się następującym błędem:
W wyrażeniu x + y, drugi z jego operandów (zmienna y) jest typu long. Typ ten może przyjmować szerszy zakres wartości niż typ zmiennej x, czyli int. Zgodnie z promocją typów, wartość wyrażenia x + y będzie więc typu long.
Kompilacja się nie powiedzie, ponieważ nie możemy przypisać do zmiennej x (która jest typu int) wartości typu long – kompilator na to nie pozwoli ze względu na potencjalną utratę danych. Zmienna x nie jest w stanie przechować wartości typu long.
Inaczej sprawa się ma w przypadku drugiej klasy, CompoundAssignmentOperator. W tym przypadku nie tylko kompilacja się powiedzie, ale także program wykona się bez błędów, a na ekranie zobaczymy liczbę 15:
W tym przypadku także dodajemy liczby o różnych typach. Dlaczego jednak tym razem kompilator nie protestuje? Spójrz na poniższy przykład:
x = (int) (x + y);
Czy tak zapisane wyrażenie jest poprawne? Tak – jawnie rzutujemy wartość wyrażenia, które, jak już ustaliliśmy, będzie typu long, na wartość typu int. Mówimy kompilatorowi: „Wiem, że mogę utracić dane, bo próbuję wartość wyrażenia typu long wcisnąć do zmiennej typu int, ale mimo to chcę to zrobić”.
Jaki to ma związek z operatorem += ? Otóż złożone operatory przypisania (compound assignment operators) wykonują dla nas niejawne rzutowanie wyliczonego wyrażenia na typ zmiennej, do której jest ono przypisywane. Oznacza to, że poniższa linia:
x += y;
jest równoznaczna z poniższą:
x = (int) (x + y);
Dzięki temu, kod drugiej klasy kompiluje się i wykonuje bez błędów.
O tym zagadnieniu możesz przeczytać bezpośrednio w oficjalnej specyfikacji języka Java.