SCJP – Operatory
Operatory przypisania opisałem zasadniczo w artykule "SCJP - Operatory przypisania dla typów prymitywnych". Na egzaminie, oprócz zwykłego operatora przypisania ‘=’ występują podobno jeszcze tylko operatory ‘+=’, ‘-=’, ‘*=’ oraz ‘/=’. Jedyną rzeczą, jaką można w tym kontekście dodać jest, że prawa strona wyrażeń z operatorami przypisania jest zawsze wyliczana jako pierwsza, tak więc wyrażenie ‘x *= 1 + 2’ jest równoważne wyrażeniu ‘x = x * (1 + 2)’ a nie ‘x = x * 1 + 2’.
Operatory arytmetyczne, mogące pojawić się na egzaminie SCJP to ‘+’, ‘-‘, ‘*’, ‘/’ i ‘%’ czyli reszta z dzielenia oraz operatory inkrementacji i dekrementacji ‘++’ oraz ‘--‘. Na komentarz zasługuje operator ‘+’. Oprócz tego, że jest on operatorem dodawania, może także być stosowany jako operator konkatenacji String’ów. Pamiętajmy, że jeśli choć jeden z operandów jest String’iem, to ‘+’ nie jest operatorem dodawania, tylko operatorem konkatenacji. Pamiętajmy także o kolejności wykonywania działań. Dla przykładu, instrukcja
System.out.println("2 plus 2 to " + 2 + 2);
powoduje wyświetlenie napisu "2 plus 2 to 22". Ale już instrukcja
System.out.println("2 razy 2 to " + 2 * 2);
daje wynik oczekiwany, tj. "2 razy 2 to 4".
Pierwszeństwo mają zawsze operatory unarne, a więc ‘++’ i ‘--‘. Następnie wykonywane są operacje ‘*’, ‘/’ oraz ‘%’ a operatory ‘+’ i ‘-‘ wiążą najsłabiej. Poza tym, jeśli kolejność wykonywania działań nie jest w pełni wyznaczona przez pierwszeństwo operatorów to są one wykonywane od lewej do prawej. W wyrażeniu >>"2 plus 2 to " + 2 + 2<< jako pierwsza wykona się więc operacja konkatenacji >>"2 plus 2 to " + 2<< której wynikiem jest "2 plus 2 to 2". Następnie, wykonana będzie konkatenacja >>"2 plus 2 to 2" + 2<< a więc w rezultacie otrzymamy napis "2 plus 2 to 22". Ponieważ jednak operator ‘*’ wiąże silniej niż ‘+’, w wyrażeniu >>"2 razy 2 to " + 2 * 2<< w pierwszej kolejności zostanie wyliczona wartość dla >>2 * 2<<, a potem wykonana będzie konkatenacja >>"2 razy 2 to " + 4<<.
Na SCJP pojawiają się także operatory logiczne. Są to ‘&’, ‘|’ i ‘^’ – które są operacjami logicznymi dla operandów typu logicznego a operacjami bitowymi dla operandów typu całkowitoliczbowego – oraz ‘&&’, ‘||’ i ‘!’. Różnica między operatorami ‘&’ i ‘|’ oraz ‘&&’ i ‘||’ zastosowanymi do operandów typu logicznego jest taka, że te pierwsze wyliczają wartość wyrażeń logicznych zachłannie a te drugie leniwie.
Operatory relacyjne ‘<’, ‘<=’, ‘>’, ‘>=’ mogą być stosowane tylko do porównywania wartości typów numerycznych i typu ‘char’, przy czym za wartość dla typu ‘char’ przyjmuje się kod Unicode znaku. Operatory ‘==’ oraz ‘!=’ można stosować dodatkowo do porównywania wartości typu logicznego i typów referencyjnych.
Operator ‘instanceof’ służy do testowania, czy referencja odnosi się do obiektu danego typu. Referencja jest operandem lewostronnym a nazwa klasy bądź interfejsu prawostronnym. Mówiąc precyzyjniej, wynikiem wyrażenia ‘x instanceof SomeClass’ jest ‘true’ gdy instancja ‘x’ IS-A ‘SomeClass’. Co to oznacza IS-A opisywałem w artykule "SCJP - Związki typu IS-A oraz HAS-A". A co, jeśli ‘x’ ma wartość ‘null’? Czy w rezultacie otrzymamy ‘NullPointerException’? Nie, wyrażenie ‘null instanceof SomeClass’ ma wartość ‘false’ i nic złego się nie dzieje. Trzeba jeszcze zaznaczyć, że operatora ‘instanceof’ nie możemy użyć, jeśli nie ma szans na powodzenie, tj. jeśli typ referencji ‘x’ nie należy do tej samej hierarchii dziedziczenia co klasa ‘SomeClass’. Nie spełnienie tego warunku jest błędem czasu kompilacji. Przykład poniżej.
public class Test {
public static void main(String[] args) {
Integer x = 5;
if(x instanceof Long) // błąd kompilacji!
System.out.println("cuda się zdarzają");
}
}