Operatory są używane do wykonywania operacji na zmiennych i wartościach.
Wartość jest nazywana operandem, podczas gdy operacja (wykonywana między dwoma operandami) jest definiowana przez
operator.
Zastosowanie. Operatory są dosyć często wykorzystywane razem z typami prostymi w ramach operacji matematycznych (takich jak dodawanie, mnożenie wartości...),
ale często są też wykorzystywane do innych zadań. Pozwalają na przykład przypisać wartość do zmiennej (bardzo często wykonywane), albo uczestniczą w porównaniach wartości.
Istnieją także operatory o zupełnie innym obszarze działania i te opisujemy na końcu rozdziału w materiałach dodatkowych.
Rodzaje operatorów
-
Operatory arytmetyczne - działają na podanych argumentach reprezentujących wartości liczbowe, w wyniku zwracając również wyznaczoną wartość liczbową. Najprościej mówiąc realizują podstawowe operacje arytmetyki:
W ramach przykładu pokażemy operator dodawania, należący do grupy operatorów arytmetycznych. W dowolnym programie możemy dodawać do siebie bezpośrednie wartości:
albo zmienną i wartość:
albo zmienną i zmienną:
Analogicznie będziemy wykonywać operacje na innych operatorach arytmetycznych.
-
Operatory przypisania - umożliwiają operację nadania, wpisania do określonej zmiennej nowej wartości:
Zobaczmy teraz następujący przykład:
Od tego momentu zmienna itemValue będzie miała w programie wartość 10. Na tak zainicowanej zmiennej
możemy wykonać operację przypisania po dodaniu. Innymi słowy, stosując ten operator jednocześnie pobieramy wartość zmiennej, następnie dodajemy ją do tej wartości,
a na końcu przypisujemy wynik z powrotem do tej samej zmiennej:
Teraz zmienna itemValue będzie miała wartość 15. Podobnie działają pozostałe operatory przypisania, z tą różnicą, że zamiast dodawania
wykonywana jest alternatywna operacja (np. mnożenie, dzielenie, procent itp.)
-
Operatory porównania - porównują argumenty równania i zwracają logiczną wartość, bazującą na sprawdzeniu czy wartość jest prawdziwa (true).
Argumenty są wartościami liczbowymi, łańcuchowymi, logicznymi lub obiektowymi. Do operatorów porównania należą działania:
Najczęściej używamy tych operatorów razem z instrukcją warunkową np. if, o której piszemy w osobnym rozdziale:
W tym przykładzie porównujemy wartość zmiennej itemValue do zmiennej maxValue. Oczekujemy, że wartość ta będzie mniejsza od wartości maksymalnej.
Tylko wtedy zostanie wykonany kod w bloku instrukcji if.
-
Operatory logiczne - działają na argumentach reprezentujących wartości logiczne, w wyniku zwracając również wartość logiczną:
Operatory te są wręcz stworzone do tego by używać ich razem z instrukcją warunkową:
W przykładzie sprawdzamy czy obie zmienne zwracają wartość logiczną PRAWDA (true). Oczekujemy, że itemVisible zwaraca true
oraz, że itemEnabled również zwraca true.
Operator && tłumaczymy jako "i". Operator || oznacza "lub". Natomiast operator !
to zaprzeczenie całego warunku, na przykład:
Powyższy zapis oznacza, że jeśli obie zmienne zwrócą true, to używając zaprzeczenia odwracamy ten wynik porównania i wtedy całość zwraca false.
Przykład w programie
Teraz zobaczmy jak typy proste wyglądają po wpięciu ich do naszego programu z rozdziału
Hello JavAPPa:
[Film bez dźwięku] [720p]
Operatory - Materiały dodatkowe
W tej sekcji przedstawiamy dodatkowe informacje oraz wprowadzamy kolejne przykłady. Warto zaznajomić się z tym materiałem, aby
poszerzyć zasób swojej wiedzy. Powodzenia!
Appa Notka.
Operator instanceof wymaga znajomości pojęć takich jak klasa, interfejs oraz dziedziczenie, dlatego, jeśli nie masz jeszcze wiedzy
z tego obszaru, polecamy najpierw zapoznać się z rozdziałami kursu z części obiektowej, która zaczyna się rozdziałem
Klasy i obiekty z życia wzięte.
Kolejne opisywane tutaj operatory, a więc operator warunkowy oraz operatory bitowe nie wymagają wiedzy z zakresu obiektowości.
Operator instanceof
Operator ten jest często wykorzystywany, choć w zasadzie powinniśmy tak pisać kod, aby korzystać z niego jak najmniej. To dosyć przewrotne stwierdzenie, ale jest w nim dużo racji, ponieważ
z jednej strony operator ten jest nieodzowną częścią języka i czasem jego użycie jest wręcz nieuniknione, a z drugiej używany w nadmiarze świadczy o nie najlepiej zaprojektowanym kodzie.
Kiedy zatem używamy słowa kluczowego
instanceof? Zawsze wtedy, gdy chcemy sprawdzić, czy dany obiekt jest oczekiwanego przez nas typu.
Na przykład chcąc sprawdzić, czy obiekt jest typu
String, użyjemy operatora
w ten sposób:
Wynik wykonania kodu:
W zależności od tego, czy do metody przekazujemy obiekt typu
String,
czy innego typu (
Integer), nasz kod zostanie obsłużony.
W przypadku gdy przekazujemy do metody tekst, wykona się jego wydruk na konsolę, a gdy przekazujemy liczbę
(obiekt typu
Integer), wydrukuje się "Other type".
Dzieje się tak, ponieważ operator porównuje obiekt do określonego typu i zwraca wartość
true, jeśli obiekt jest danego typu lub
false, gdy obiekt jest innego typu.
Jak to będzie wyglądać w bardziej zaawansowanym przykładzie? Załóżmy, że mamy metodę, która
przyjmuje jako parametr obiekt klasy
Item. My jednak wiemy, że tak naprawdę dostajemy tam zawsze obiekt jednej z klas dziedziczących, powiedzmy -
MovieItem
lub
SongItem. Interesuje nas wykonanie kodu metody tylko dla przypadku gdy otrzymamy obiekt typu
MovieItem. W takiej sytuacji możemy wykorzystać
opisywany tutaj operator:
Na koniec warto dodać, że już niedługo w Javie pojawi się finalne rozwiązanie pozwalające na połączenie sprawdzenia
typu z jego deklaracją i nazwą zmiennej. Obecnie musimy wykonywać rzutowanie. Kiedy się pojawi taka opcja?
Nie wiadomo. Może już w Javie 16. Zobaczymy.
Aktualnie (czyli w Java 15) jest ona dostępna w trybie
preview.
Operator warunkowy
Kolejnym operatorem jest operator warunkowy zwany z angielskiego
ternary. Warto zapamiętać tę nazwę w obu językach, ponieważ podczas rozmowy kwalifikacyjnej, czy też w nowej pracy,
można być o to zapytanym na różny sposób (nazwa angielska tego operatora jest dosyć popularna).
Konstrukcja operatora wygląda mało atrakcyjnie:
Dlatego od razu zobaczmy przykład:
Ten mało błyskotliwy kawałek kodu dobrze pokazuje działanie operatora. Najpierw przypisujemy wartość 7 do zmiennej typu
int,
a następnie wykonujemy wydruk tekstu na konsoli. To, co będzie wydrukowane, zależy od wyniku działania operatora
ternary. Najpierw przed znakiem zapytania wprowadzamy
warunek, który ma być przetestowany.
W przypadku gdy warunek zwróci wartość true, wykonuje się
kod zaraz po znaku zapytania. W przypadku gdy warunek zwróci false (co jak wiemy, w tym przykładzie akurat jest niemożliwe)
wówczas wykona się
kod po dwukropku. Innymi słowy, w przypadku true do metody
println zostanie przekazany tekst "prawda", a w przeciwnym wypadku tekst "fałsz".
Warto wkleić powyższy kawałek kodu do programu, by zobaczyć, że wydrukowane zostanie słowo "prawda". W ramach ćwiczenia polecamy również zmienić wartość zmiennej
someValue na inną wartość, na przykład 5.
Wtedy warunek zwróci false i na konsoli zobaczymy wydruk "fałsz".
Operatory bitowe
Wielu z początkujących programistów nie lubi operatorów bitowych, ponieważ na pierwszy rzut oka wydają się one być skomplikowane.
Prawda jest jednak taka, że to nie operatory są problemem. One jedynie bazują na logice matematycznej, nad którą nie zastanawiamy się na co dzień.
Mowa tutaj o liczbach binarnych i operacjach, jakie możemy na nich wykonywać.
Dlatego warto najpierw zaznajomić się z takimi pojęciami matematycznymi jak:
koniunkcja (AND), alternatywa (OR), negacja (~), alternatywa wykluczająca (XOR).
W przypadku operacji na bitach (odpowiednia kombinacja 0 i 1 tworzących liczbę) pojęcia te są realizowane w następujący sposób:
Przesunięcie bitowe
Operatory realizujące przesunięcie bitowe również nie są ulubioną częścią nauki, choć tak naprawdę same w sobie są dosyć proste do zrozumienia.
W Javie rozróżniamy operatory:
Signed Right shift (>>), Left shift (<<) oraz
Unsigned right shift (>>>).
Wszystkie służą do przesuwania bitów w określoną stronę w liczbie przedstawionej w systemie binarnym i wypełniania miejsc po opuszczonych pozycjach z prawej lub lewej strony liczby.
Appa Notka. Zanim przejdziemy do omówienia przykładu z przesunięciami bitowymi,
niezwykle ważne jest zapoznanie się z podstawową regułą obsługi liczb binarnych w Javie.
W języku tym używa się dopełnienia do dwóch (Two's Complement).
Na przykład dla liczb 3 i -3 binarne formaty określamy w ten sposób:
Format binarny dla 3 (zapisany na 8 bitach): 0000 0011
Format binarny dla -3 (zapisany na 8 bitach): 1111 1101
Dlaczego -3 wygląda akurat tak? Właśnie dlatego, że używamy tutaj dopełnienia do dwóch:
0000 0011 <--- format binary liczby 3
1111 1100 <--- odwrócenie bitów (0 na 1 i 1 na 0)
1111 1101 <--- dodanie 1
Tak to wygląda na wydruku z konsoli:
Linki:
https://www.w3schools.com/java/java_operators.asp
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
Two's Complement
Masz pytanie dotyczące prezentowanego materiału?
Coś jest dla Ciebie niejasne i Twoje wątpliwości przeszkadzają Ci w pełnym zrozumieniu treści?
Napisz do nas maila, a my chętnie znajdziemy odpowiednie rozwiązanie.
Najciekawsze pytania wraz z odpowiedziami będziemy publikować pod rozdziałem.
Nie czekaj. Naucz się programować jeszcze lepiej.