Rozdział 3 - Zmienne - Typy podstawowe

Znając już zasady dotyczące nadawania nazw w Javie, wróćmy do programu liczącego pole i obwód koła, który używa czterech zmiennych:

Nazwa pliku: ObwodPoleKola.java
public class ObwodPoleKola {
  public static void main(String[] args) {
    int promienKola = 8;
    double pi = 3.14;

    double poleKola = pi * promienKola * promienKola;
    double obwodKola = 2 * pi * promienKola;

    System.out.println("Pole kola wynosi: " + poleKola);
    System.out.println("Obwod kola wynosi: " + obwodKola);
  }
}

Program ten korzysta z jednej zmiennej liczbowej typu całkowitego int, oraz trzech zmiennych liczbowych typu zmiennoprzecinkowego double.

Typ zmiennej to informacja, jakiego rodzaju wartości zmienna będzie mogła przechowywać. Zmienna promienKola będzie służyła do przechowywania liczb całkowitych, a zmienne pi, poleKola, oraz obwodKola, będą mogły mieć wartości liczb rzeczywistych (czyli będą mogły mieć część ułamkową).

Typy zmiennych dzielimy na dwa rodzaje:

  • typy prymitywne,
  • typy złożone.

Język Java posiada 8 następujących typów prymitywnych, które są typami predefiniowanymi przez dany język programowania (w przeciwieństwie do typów złożonych, które definiują programiści – wkrótce dowiemy się więcej na ten temat):

Nazwa Zakres Wartości Opis Przykład
boolean true lub false Typ logiczny – przyjmuje wartości prawda (true) bądź fałsz (false). true
byte od -128 do 127 8-bitowa liczba całkowita. 10
short od -32768 do 32767 16-bitowa liczba całkowita. 1500
int od -2147483648
do 2147483647
32-bitowa liczba całkowita. 1000000
long od -2^63 do 2^63 - 1 64-bitowa liczba całkowita. 10000000000L
float Liczby rzeczywiste 32-bitowa liczba zmiennoprzecinkowa (floating-point). 3.14f
double Liczby rzeczywiste – większy zakres 64-bitowa liczba zmiennoprzecinkowa (double-precision). 3.14
char 0 do 216-1 Typ znakowy – jeden 16-bitowy znak Unicode. 'z'

Definiując zmienną, podajemy jej typ zgodnie z tym, jakie wartości chcemy w danej zmiennej przechowywać. Język Java jest językiem typowanym, co oznacza, że zmienne mają typ określony przy ich definiowaniu przez programistę i nie może się on zmienić w trakcie wykonywania programu, tzn. zmienna typu całkowitego może przechowywać jedynie wartości liczbowe typu całkowitego.

Spójrzmy na poniższy przykład – zmiennej liczbaOkien podczas definicji został nadany typ int. W kolejnej linii, próbujemy przypisać do tej zmiennej wartość rzeczywistą:

Nazwa pliku: UstalonyTyp.java
public class UstalonyTyp {
  public static void main(String[] args) {
    int liczbaOkien;

    liczbaOkien = 3.5; // blad!
  }
}

Kompilacja tego programu nie powiedzie się, ponieważ do zmiennej, która miała przechowywać liczby całkowite, próbowaliśmy przypisać liczbę rzeczywistą:

UstalonyTyp.java:5: error: incompatible types: possible lossy conversion from double to int liczbaOkien = 3.5; ^ 1 error

Kompilator wie, że zmienna liczbaOkien nie może przechowywać części ułamkowej przypisywanej do niej wartości (bo typ int określa jedynie liczby całkowite), więc ewentualne przypisanie wartości 3.5 do zmiennej liczbaOkien spowodowałoby stratę części wartości – kompilator na to nie pozwoli i nie skompiluje naszego programu.

Literały

Aby nadać wartości zmiennym typów podstawowych, musimy je zapisać w kodzie programu.

Liczby takie jak 10, 3.14, znaki, jak np. 'A', 'N', tekst ujęty w cudzysłowy np. "Witaj Swiecie!" oraz wartości logiczne true i false, to tzw. literały. Umieszczone w kodzie źródłowym reprezentują po prostu konkretne wartości danego typu:

Nazwa pliku: LiteralyPrzyklad.java
public class LiteralyPrzyklad {
  public static void main(String[] args) {
    int liczbaCalkowita = 10;
    double liczbaRzeczywista = 2.5;
    char znak = 'A';
    boolean wartoscLogiczna = true;
  }
}
Zwróć uwagę, że literał znakowy dla zmiennej znak zapisany jest w apostrofach, a nie cudzysłowach – za chwilę opowiemy sobie, dlaczego.

Typy całkowite i zmiennoprzecinkowe

Zgodnie z tabelą typów prymitywnych, język Java posiada cztery typy liczb całkowitych (byte, short, int, long), a także dwa typy liczb zmiennoprzecinkowych float i double.

Po co nam kilka typów o taki samych rodzajach wartości, ale inny zakresach?

Wynika to z faktu, iż większy zakres oznacza, że zmienna będzie potrzebować więcej miejsca na swoją wartość. W dawnych czasach miało to duże znaczenie, gdy pamięć w komputerach była dużo bardziej ograniczona.

Zmienne typu byte mogą przechowywać wartości nie większe, niż 127, a zmienne typu int – nie większe, niż 2147483647 – zobaczmy, co stanie się, gdy spróbujemy przypisać do nich większe wartości:

Nazwa pliku: ZaDuzaWartoscByte.java
public class ZaDuzaWartoscByte {
  public static void main(String[] args) {
    byte malaLiczba = 123;

    // blad - wartosc przekracza zakres typu byte
    malaLiczba = 10000;
  }
}
Nazwa pliku: ZaDuzaWartoscInt.java
public class ZaDuzaWartoscInt {
  public static void main(String[] args) {
    int duzaLiczba = 12345;

    // blad - wartosc przekracza zakres typu int
    duzaLiczba = 9999999999;
  }
}

Kompilacja zakończy się błędem w przypadku obu powyższych programów:

ZaDuzaWartoscByte.java:6: error: incompatible types: possible lossy conversion from int to byte malaLiczba = 10000; ^ 1 error
ZaDuzaWartoscInt.java:6: error: integer number too large duzaLiczba = 9999999999; ^ 1 error
Typ prymitywny określa nie tylko, jakiego rodzaju wartości zmienna może przechowywać, ale także jaki jest zakres tych wartości.

W trakcie nauki, będziemy stosować typ int – jest to domyślny typ liczb w kodzie Java – jeżeli kompilator widzi w kodzie źródłowym literał liczby całkowitej (np. 10), to traktuje go jako wartość typu int. Domyślnym typem wartości rzeczywistych (zmiennoprzecinkowych) jest typ double i taki też typ będziemy stosować w kursie.

Wróćmy jeszcze na chwilę do tabeli typów podstawowych – przykład wartości dla typu long ma na końcu liczby literę L: 10000000000L. Nie jest to błąd w tabeli – jak już wspomnieliśmy, kompilator domyślnie traktuje wszystkie literały liczb całkowitych, które napotka w kodzie, jako liczby typu int. Gdybyśmy zapisali w kodzie Java liczbę 10000000000, to kompilator zgłosiłby błąd – ta wartość jest zbyt duża dla typu int. Aby jednak móc w kodzie zapisywać większe liczby, które będziemy mogli umieścić w zmiennych typu long (który to typ ma dużo większy zakres, niż typ int), należy na końcu liczby dopisać literę L (mała lub wielką, ale wielka jest bardziej czytelna):

Nazwa pliku: LiczbaLong.java
public class LiczbaLong {
  public static void main(String[] args) {
    long wielkaLiczba;

    // linia zakomentowana, poniewaz spowodowalaby blad kompilacji!
    // wielkaLiczba = 10000000000;

    // dopisalismy L na koniec – kompilator wie, ze będzie to duza liczba
    wielkaLiczba = 10000000000L;
  }
}

Powyższy kod kompiluje się bez problemów, dzięki zastosowaniu suffixu L przy dużej liczbie.

Podobnie rzecz ma się z liczbami typu double i float – jeżeli chcemy przypisać wartość rzeczywistą do zmiennej typu float, musimy użyć suffixu f.

Typ boolean

Typ boolean służy do przechowywania wartości typu prawda / fałsz – zaczniemy z niego korzystać w rozdziale o instrukcjach warunkowych.

Typ char

Typ char przechowuje pojedyncze znaki, które ujmujemy w apostrofy ' ', w przeciwieństwie do stringów (łańcuchów tekstowych), które zawieramy między cudzysłowami. W apostrofach może być zawarty co najwyżej jeden znak.

W poniższym przykładzie nieprawidłowo przypisujemy wartość do zmiennej znak w drugiej i trzeciej linii:

char znak;
znak = 'ABC';    // blad - maksymalnie jeden znak
znak = "Witaj!"; // blad – "Witaj!" to nie jest znak, lecz lancuch znakow
znak = 'X';      // poprawne przypisanie - jeden znak

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.