Zagadka Java #2

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:

AssignmentOperator.java:6: error: incompatible types: possible lossy conversion from long to int x = x + y; ^ 1 error

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:

$ javac CompoundAssignmentOperator.java $ java CompoundAssignmentOperator 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.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Nie musisz podawać swojego imienia, e-mailu, ani strony www, aby opublikować komentarz. Komentarze muszą zostać zatwierdzone, aby były widoczne na stronie.