Poprzedni wpis Java – wstęp i instalacja
W Javie każda zmienna jest ściśle określonego typu, który może być:
Java jest językiem przenośnym zatem na każdej maszynie zmienne zapisywane są w ten sam sposób. Z góry znane są rozmiary każdego typu prostego i nie istnieje sytuacja znana np. z języka C, w którym zachodzi następująca relacja:
short int <= int <= long.
Każdy kompilator może luźno podejść do ustalenia rozmiarów zatem jest to zależne wyłącznie od człowieka, który uznał, że określona wartość najlepiej spełnia swoje zadanie na konkretnej maszynie. Podejście ukazane w Javie eliminuje te problemy z uruchamianiem programów na innych komputerach lub systemach.
Przygodę z danymi rozpoczniemy od najprostszych elementów jakimi są typy proste. W tej części przedstawimy wszystkie zmienne jakie są dostępne w Javie oraz podamy podstawowe informacje o nich.
Zakres liczb całkowitych w Javie jest następujący dla podanych typów zmiennych.
1 2 |
int liczbaPlanet = 8; //obecnie znana liczba planet w Układzie Słonecznym long liczbaGwiazd = 400000000000L; //szacowana liczba gwiazd w Drodze Mlecznej |
Java nie posiada typu unsigned, w związku z tym nie można rozszerzyć zakresu zmiennej przez interpretację bitu znakowego jako część wartości zmiennej. Jeśli chcemy zapisać liczbę 3 miliardy musimy użyć typu long. Najczęściej wykorzystywanym typem całkowitoliczbowym jest int
i w większości zastosowań jego wartości są wystarczające – jeśli nie jest to podyktowane innymi uwarunkowaniami zalecamy korzystać z tego typu.
Te typy danych Przechowują dodatkowo część ułamkową. Zakres liczb zmiennoprzecinkowych w Javie jest następujący dla podanych typów zmiennych.
1 2 |
float pojemnoscSilnika = 4.0F; double pi = 3.141592653589D; |
Każda zmienna logiczna posiada tylko dwie wartości – true i false. Zapisuje się ją jako boolean. Wartość logiczną może zwrócić także wyrażenie porównujące zmienne operatorami (==, <, >). Ten typ jest podstawą przepływu sterowania w programie.
1 2 |
boolean isNull = true; System.out.print(a == b); //zostanie wypisana wartość tego wyrażenia |
Zmienna znakowa char reprezentuje pojedyncze znaki przy pomocy kodowania Unicode (więcej szczegółów o różnych sposobach kodowania znaków).
Znaki, takie jak cudzysłów zapisuje się jako \”, a ukośnik jako \\. Jest to spowodowane tym, że te znaki mają też inne zastosowanie. Dlatego należy poinformować kompilator, że chcemy umieścić znak nie jako część składni języka, a jako wartość zmiennej. Szczególnie należy zwrócić uwagę na cudzysłowy oraz ukośniki, gdyż częstym błędem jest umieszczenie ich po prostu np. w łańcuchu znakowym, który wskazuje lokalizację na dysku. Poniżej znajduje się pełna lista takich symboli.
\b \t \n \f \r \” \’ \
1 2 |
char = 'a'; char = '\"'; |
Zmienna wyliczeniowa przydaje się w przypadku, gdy zbiór wartości jest dyskretny np. rozmiary pizzy w menu restauracji.
1 |
enum RozmiarPizzy {MALA, SREDNIA, DUZA}; |
zmienna wyliczeniowa RozmiarPizzy może przyjmować tylko zadeklarowane wartości lub wartość null.
Zmienne i stałe mają określony typ, mają nazwę oraz wartość. Z punktu widzenia komputera ważne jest wiedzieć, gdzie znajduje się zmienna (jaki posiada adres w pamięci). Dlaczego typ jest taki ważny? Każdy typ zajmuje określoną przestrzeń w pamięci, więc komputer, aby prawidłowo odczytać wartość musi wiedzieć czy będzie to wartość o rozmiarze 4 bajtów jak int, czy też 1 bajt na znak. Na szczęście nas nie interesuje adres komórki w pamięci, a nazwa zmiennej, którą dużo łatwiej operować. Nazwę traktujemy jako etykietę, która po wpisaniu wskaże odpowiednie miejsce w pamięci komputera.
Aby użyć zmiennej należy ją zadeklarować i zainicjować, można to zrobić oddzielnie.
1 2 |
int zmienna; zmienna = 10; |
Lub w jednym wierszu
1 |
int zmienna = 10; |
Podobnie używamy innych typów nadając im odpowiednie wartości. pokazuje to poniższy listing.
1 2 3 |
int dni = 10; float cena = 2.45f boolean isNull = true; |
Słowo kluczowe final oznacza deklarację stałej. Ich nazwy zalecamy pisać wielkimi literami, a w przypadku wieloczłonowej nazwy oddzielać je znakami podkreślenia.
1 2 |
final double PI = 3.1415d; final int MIESIACE_W_ROKU = 12; |
W Javie zmienne, stałe i klasy możemy nazywać w zasadzie dowolnie pamiętając o kilku wyjątkach:
Długość zmiennej może być dowolna, natomiast z dobrej praktyki należy dobierać nazwy zmiennych zgodnie z ich zastosowaniem. Czasami trzeba zastosować dłuższą nazwę, dlatego zalecamy używanie notacji camelCase – czyli pierwsze słowo zaczynamy małą literą, a każde następne – wielką. Poniżej znajdują się przykłady poprawnych nazw zmiennych.
1 2 3 |
int dni = 10; float dlugoscBoku = 2.4f; double objetosc = 1,5634d; |
W Javie miejsce inicjacji zmiennej jest dowolne (byle było przed jej użyciem), w związku z tym zaleca się, aby inicjować je jak najbliżej pierwszego użycia.
1 2 3 4 5 |
{ ... int dni = 10; System.Out.Println(dni); } |
Zmienne widoczne są po ich zainicjowaniu. Na tym etapie nie będziemy wchodzić w widoczność zmiennych z użyciem modyfikatorów dostępu (o tym napiszemy dokładnie w następnym artykule poświęconym klasom w Javie – wstęp do programowania obiektowego). Ważne aby pamiętać, że zmienna, która została zainicjowana wewnątrz bloku nie jest widoczna poza nim.
1 2 3 4 5 |
... { int zmienna; } System.Out.Println(zmienna); //błąd, zmienna nie jest widoczna poza blokiem! |
Natomiast sytuacja odwrotna jest jak najbardziej prawidłowa.
1 2 3 4 |
int zmienna; { System.Out.Println(zmienna); //poprawnie, zmienna jest widoczna wewnątrz bloku } |
Zapewne Twojej uwadze nie umknęła treść po dwóch znakach //. Jest to komentarz czyli fragment, który kompilator całkowicie pomija. Komentarze mogą być pomocne przy opisie zmiennych np. co robią, opisywać co robi dana metoda lub wskazywać dany fragment kodu źródłowego, aby łatwiej było go później modyfikować. Występują dwa typy komentarzy:
1 2 3 4 5 |
//to jest komentarz krótki /* to jest komentarz blokowy kończy się dopiero specjalnym znakiem */ |
Konwersje typów są konieczne w przypadku, gdy np w działaniu arytmetycznym operandy są różnego typu (np. int i float). Część z nich może odbywać się niejawnie (automatycznie), a część musi być przeprowadzona przez rzutowania (ang. cast). Podstawową cechą Javy jest zapobieganie częstym błędom programistów zatem gdy konwersja może spowodować utratę danych, wymagane jest jawne rzutowanie typów.
Najważniejsze problemy jakie mogą wyniknąć to:
Automatyczne rzutowanie przebiega wg. poniższych zasad zasad:
Konwersje następują w taki sposób, aby nie utracić danych. W przypadku typów całkowitych występuje następująca konwersja.
Liczby zmiennoprzecinkowe konwertują się na double.
W przypadku działania na typach zmiennoprzecinkowych i całkowitoliczbowych zawsze nastąpi konwersja na ten pierwszy typ float lub double.
1 2 |
int a = 1; float f = a; //niejawna konwersja na 1.0f |
Jeżeli potrzebujemy konwersji typu zmiennoprzecinkowego na typ całkowity, to należy jawnie rzutować.
1 2 |
float f = 1.99f; int a = (int) f; //wartość f wynosi 1 |
Aby zaokrąglić wartości należy skorzystać z metod klasy Math
(np. Math.round()
, Math.floor()
).
Uwaga! W przeciwieństwie do języka C++ w Javie nie istnieje rzutowanie typu liczbowego na logiczny!
1 2 |
int a = 1; boolean b = (boolean) a //błąd! |
Operatory posiadają priorytet działania (podobnie jak kolejność wykonywania działań). Jeśli kolejne operatory mają ten sam priorytet działania, to działanie wykonywane jest od lewej strony. Jeśli nie mamy pewności najlepiej zastosować nawiasy.
W następnej części przyjrzymy się bliżej łańcuchom znakowym, klasie String oraz tablicom.
About the author