Wprowadzenie do programowaia w języku Java dr Dariusz Pałka email: dpalka@up.krakow.pl
Dlaczego Java?* W oparciu o technologię Java pracuje 4,5 mld. urządzeń Ponad 800 mln. komputerów 2,1 mld. telefonów komórkowych i innych urządzeń przenośnych 3,5 mld kart chipowych dekodery TV, drukarki, kamery internetowe, gry, samochodowe systemy nawigacji, terminale loteryjne, urządzenia medyczne, parkomaty i inne *Na podstawie strony www.javasoft.com (z dnia 21.09.2009)
Dlaczego Java? cd Java została wybrana przez ponad 6,5 mln. programistów Pozwala na: uruchamianie programów pisanych na jednej platformie na praktycznie dowolnej innej platformie (na której istnieje VMJ) tworzenie programów, możliwych do uruchomienia z poziomu przeglądarki internetowej i usług sieciowych łączenie aplikacji lub usług wykorzystujących język Java w celu stworzenia aplikacji i usług ściśle dostosowanych do potrzeb
Dlaczego Java? cd Pozwala na: opracowywanie aplikacji serwerowych obsługujących fora internetowe, sklepy internetowe, ankiety, formularze HTML i wiele innych łączenie aplikacji lub usług wykorzystujących język Java w celu stworzenia aplikacji i usług ściśle dostosowanych do potrzeb pisanie efektywnych aplikacji dla telefonów komórkowych, procesorów zdalnych, tanich produktów powszechnego użytku oraz praktycznie każdego innego urządzenia opartego na układach cyfrowych
Cechy języka JAVA Łatwy (stosunkowo) Zorientowany obiektowo Oparty na języku C++ Bezpieczny Sprzętowo niezależny Wielowątkowy Wspierający programowanie sieciowe i rozproszone
Cykl tworzenia programu
Uruchomienie programu
Środowisko wykonawcze JAVA (JRE)
Krótka (pre)historia języka JAVA 1967 opracowanie języka LOGO 1970 opracowanie języka Pascal 1969-1973 opracowanie języka C Lata 80-te 20-go wieku powstanie języka C++ 1991 - Projekt Green (James Gosling) powstanie języka OAK - Object Application Kernel 1995 - zmiana nazwy z OAK na JAVA 1996 - Netscape zgodny z Java 1.0, Sun darmowe JDK 1.0 1999 Platforma Java 2
Typy programów w języku JAVA Samodzielne programy z interfejsem tekstowym z interfejsem graficznym Aplety działające w środowisku przeglądarki WWW Rozszerzenia stron WWW w interpretowanym języku opartym na JAVIE - JavaScript Serwlety rozszerzające możliwości serwera WWW Java FX Script
JAVA jako język sieciowy Cechy JAVY przydatne w aplikacjach sieciowych: Niezależność platformowa Bezpieczeństwo Wbudowany międzynarodowy zestaw znaków Bogate API umożliwiających korzystanie z rozwiązań sieciowych Własne technologie sieciowe(np. RMI)
JAVA jako język sieciowy Cechy JAVY przydatne w aplikacjach sieciowych: Niezależność platformowa Bezpieczeństwo Wbudowany międzynarodowy zestaw znaków Bogate API umożliwiających korzystanie z rozwiązań sieciowych Własne technologie sieciowe(np. RMI)
Możliwości programów sieciowych Pobieranie i wyświetlanie danych w różnych formatach Możliwość wprowadzania nowych formatów danych (inaczej niż w przeglądarkach WWW) Łączenie danych w różnych formatach Przetwarzanie danych przed ich prezentacją Elastyczność w prezentacji danych
Możliwości programów sieciowych Powtarzalne pobieranie danych Powtarzalne pobieranie danych Wysyłanie danych Równoległe obliczenia rozproszone Komunikacja każdy z każdym Gry Pogawędki Programy typu whiteboard Przeszukiwanie WWW Handel elektroniczny
Przykładowa aplikacja
Przykładowe aplety
Wstęp do programowania w języku JAVA
Pierwszy program public class PierwszyProgram { public static void main(string[] args) { System.out.println( Czesc! );
Obiekty w języku JAVA Wszystkie (prawie) byty w JAVIE to obiekty Manipulowanie obiektami odbywa się poprzez referencje do nich
Obiekty w języku JAVA Stworzenie referencji do obiektu klasy String: String s; Powyższa linia tworzy tylko referencje a nie obiekt, co więcej referencja ta nie wskazuje na żaden obiekt. Bezpieczniejszą techniką jest tworzenie i jednoczesne inicjalizowanie referencji : String s = abcdefgh ;
Obiekty w języku JAVA Trzeba tworzyć wszystkie obiekty: String s = new String( abcdefgh ); Powyższa linia tworzy nowy obiekt klasy String i przypisuje referencje do niego do zmiennej s. Linia ta określa też jak ma być skonstruowany obiekt klasy String jakim ciągiem znaków ma być zainicjalizowany
Typy proste typ rozmiar min max boolean - - - char 16bitów unicode 0 unicode 2 16-1 byte 8bitów -128 +127 short 16bitów -2E15 +2E15-1 int 32bity -2E31 +2E31-1 long 64bity -2E63 +2E63-1 float 32bity IEEE754 IEEE754 double 64bity IEEE754 IEEE754 void - - -
Typy proste boolean char byte short int long float double void typ opakowanie obiektowe Boolean Character Byte Short Integer Long Float Double Void
Słowa kluczowe abstract continue for new switch assert default if package synchronized boolean do goto private this break double implements protected throw byte else import public throws case enum instanceof return transient catch extends int short try char final interface static void class finally long strictfp volatile const float native super while
Zasięg nazw Zasięg określa widzialność i czas życia zdefiniowanej nazwy. Zasięg jest ograniczany przez nawiasy klamrowe {. Przykład: { int x = 12; /* w tym miejscu tylko zmienna x jest dostepna */ { int q = 96; /* tu sa dostepne zmienne x i q */ /* tu tylko zmienna x jest dostepna */ /* zmienna q jest poza zasiegiem */
Zasięg nazw Inaczej niż w c++ w JAVIE nie ma przykrywania zmiennych Przykład: { int x = 12; { int x = 96; /* niepoprawne w JAVIE */
Zasięg obiektu Zasięg obiektów jest w JAVIE inny niż typów prostych: { String s = new String( abc ); /*koniec zasiegu */ /* referencja s jest poza zasiegniem wiec nie ma do niej dostepu. Natomiast obiekt String ciagle istnieje i zajmuje pamiec (ale nie ma do niego dostepu bo nie istnieje już żadna referencja do niego) */
Garbage collector W JAVIE część systemu zwana garbage collector jest odpowiedzialna za usuwanie niepotrzebnych obiektów z pamięci Nie można* i nie trzeba samemu decydować kiedy obiekt ma zostać zniszczony. Jedynie wiadomo kiedy obiekty typów prostych są niszczone.
Klasy Klasa definiuje zachowanie obiektów, będących instancjami tej klasy czyli służy do definiowania typu: class NazwaTypu { /*definicja*/ Tworzenie obiektu (instancji) tej klasy: NazwaTypu o = new NazwaTypu();
Klasy Klasa może zawierać dwa typy elementów: Pola (dane) będące instancjami innych obiektów, lub typów prostych Metody (funkcje) będące operacjami przeprowadzanymi na obiekcie, bądź klasie
Klasy - pola Przykład klasy zawierającej tylko pola: class Dane { int i; float f; /*... */ Dane d = new Dane(); d.i = 32; d.f = 23.6f;
Klasy - pola Dostęp do składowych (pól i metod) odbywa się poprzez kropkę: refernecjadoobiektu.skladowa np.: d.i = 32; lub: kologlowne.srodek.x = 23;
Klasy - pola Diagram klasy Dane w UML u
Klasy - metody Metody służą do wykonywania operacji na obiekcie (lub klasie), określają one, jakie komunikaty rozumieją obiekty klasy. Podstawowymi składnikami metody są: nazwa, argumenty, zwracany typ oraz ciało metody: zwracanytyp nazwametody(/*argumenty*/) { /* cialo metody */ W JAVIE metody mogą być jedynie składowymi klas!
Klasy - metody Przykładowa funkcja (musi być zdefiniowana wewnątrz klasy) która pobiera jeden argument typu String i zwraca int: int foo(string s) { return s.length() * 2; Funkcja bezargumentowa, nic nie zwracająca: void fun() { /* zrob cos */ return; /* return może być pominiete */
Słowo kluczowe static Poprzedzenie składowej (pola, metody) słowem static oznacza, że ta składowa odnosi się do klasy a nie do obiektu. Jest ono użyteczne gdy: Chcemy aby jakieś pole było współdzielone przez wszystkie obiekty danej klasy, lub żeby istniało gdy nie istnieją jeszcze żadne obiekty tej klasy Potrzebujemy metody, która nie jest związana z żadnym konkretnym obiektem klasy
Słowo kluczowe static Przykład: class StaticTest { static int i = 47; StaticTest st1 = new StaticTest(); StaticTest st2 = new StaticTest(); st1.i++; /* dostep przez obiekt */ StaticTest.i++; /* dostep przez klase */
Słowo kluczowe static Przykład cd: class StaticFun { static void zwieksz() { StaticTest.i++; /*... */ StaticFun.zwieksz();
Kompletny program w JAVIE import java.util.*; public class DrugiProgram { public static void main(string[] args) { System.out.println( Hey, dzisiaj jest: ); System.out.println(new Date());
Operatory
Operator przypisania = Operator ten przypisuje elementowi po lewej stronie wartość elementu znajdującego się po prawej stronie. Nie można przypisywać niczego do elementów stałych: a = 4; /* przypisanie wartosci 4 do zmiennej a */ 4 = a; /* BLAD proba przypisania do stalej */ Dla typów prostych przypisanie oznacza skopiowanie zawartości. Dla typów obiektowych, w przypadku których manipulujemy referencjami, przypisanie oznacza ustawienie referencji będącej po lewej stronie operatora na obiekt wskazywany przez referencję po prawej stronie operatora.
Operator przypisania = Przykład: class Numer { int i; public class TestPrzypisania { public static void main(string[] args) { Numer n1 = new Numer(); Numer n2 = new Numer(); n1.i = 10; n2.i = 18; n1 = n2; /*referencja n1 wsk. na obiekt w wsk. przez n2*/ n1.i = 132; /*n2.i jest tez teraz rowne 132*/
Operatory matematyczne Dodawanie (+) Odejmowanie (-) Mnożenie (*) Dzielenie (/) Modulo (%)
Operatory matematyczne Przykład: a = b + c; e = a * 7; f -= 10; /* to samo co f = f 10; */ g = f % 4; /* g ma wartosc reszty z dzielenia f przez 4 */
Operatory matematyczne Jednoargumentowe operatory + i - a = -b; d = +b; c = a * -b; C = a * (-b); /* bardziej czytelna wersja */
Operatory matematyczne Auto inkrementacja (++) i dekrementacja (--) Istnieją dwie formy auto inkrementacji i dekrementacji pre i post ++a; /* pre-inkrementacja */ b--; /* post-dekrementacja */
Operatory matematyczne Przykład: public class AutoInc { public static void main(string[] args) { int a = 0; int x = 0; x = a++; /* x ma wartosc 0 */ x = a; /* x ma wartosc 1 */ a = 0; x = ++a; /* x ma wartosc 1 */ x = a; /* x dalej ma wartosc 1 */
Operatory porównania Wszystkie operatory porównania zwracają wynik typu boolean (true lub false) Operator równości (==) Operator nierówności (!=) Operator mniejszości (<) Operator większości (>) Operator mniejszy lub równy (<=) Operator większy lub równy (>=)
Operatory porównania Porównanie obiektów wersja 1: public class Porownanie1 { public static void main(string[] args) { Integer n1 = new Integer(56); Integer n2 = new Integer(56); System.out.println(n1 == n2); System.out.println(n1!= n2);
Operatory porównania Porównanie obiektów wersja 2: public class Porownanie2 { public static void main(string[] args) { Integer n1 = new Integer(56); Integer n2 = new Integer(56); System.out.println(n1.equals(n2));
Operatory = > <! ~? : == <= >=!= && ++ -- + - * / & ^ % << >> >>> += -= *= /= &= = ^= %= <<= >>= >>>= http://java.sun.com/docs/books/tutorial/java/nutsandbolts/opsummary.
Operatory rzutowania (konwersji) int i = 10; long l1 = (long)10 long l2 = (long)i; byte b = (byte)i; W języku Java dozwolone jest rzutowanie dowolnego typu prostego na inny (poza typem boolean, który nie może być użyty w rzutowaniu) Nie jest dozwolone rzutowanie typów obiektowych (poza rzutowaniem na String, oraz rzutowaniem w ramach hierarchii dziedziczenia)
Promocja typów Stosowanie operatorów matematycznych lub bitowych na danych typów prostych mniejszych niż int (char, byte, short) powoduje, że wartości są rozszerzane (promowane) do typu int przed wykonaniem operacji, a wynik operacji jest również typu int
Wyrażenie warunkowe Postać wyrażenia warunkowego: boolean-exp? value0 : value1 W przypadku gdy boolean-exp ma wartość true wyrażenie przyjmuje wartość value0, natomiast w przypadku gdy ma wartość false wyrażenie przyjmuje wartość value1. Przykład: static int abs(int v) { return v > 0? v: -v;
Instrukcje
; Instrukcja pusta
Instrukcja deklaracji zmiennej int x = 16; double[] tab = new double[100];
Instrukcja bloku programu { int x = 16; x++; int k = 2*x;
Instrukcje sterujące wykonywaniem programu
Instrukcja warunkowa if-else Składnia: if( Boolean-expression ) statement else statement lub: if( Boolean-expression ) statement
Pętla while Składnia: while( Boolean-expression ) statement
Pętla for Składnia: for(initialization; Boolean-exp; step) statement
Instrukcja break Instrukcja break służy do przerywania wykonywania bieżącego poziomu pętli. Przykład: static void breaktest(int v) { for( int i = 0; i < 100; i++ ) { if( v/i < 10 ) break; System.out.println(i);
Instrukcja break cd. Przykład 2: static void breaktest2() { int i = 0; while( true ) { if( i > 100 ) break; System.out.println(i); i++;
Instrukcja continue Instrukcja continue przerywa wykonywanie bieżącej iteracji pętli i przechodzi do następnej iteracji rozpoczynając od początku ciała pętli. Przykład: static void continuetest() { for( int i = 0; i < 100; i++ ) { if( i % 10 < 2 ) continue; System.out.println(i);
Instrukcja wyboru switch Składnia: switch(integral-selector) { case integral-val1: statement; break; case integral-val2: statement; break; case integral-val3: statement; break; //... default: statement;
Instrukcja wyboru switch cd. public static void switchtest(int v) { int r = v %4; switch(r) { case 0: System.out.println( Podzielna przez 4 ); break; case 1: System.out.println( Reszta z dzielenia wynosi 1 ); break; //...
Inicjalizacja i niszczenie obiektów w Javie
Konstruktor Konstruktor jest metodą klasy służącą do inicjalizacji nowo tworzonych obiektów tej klasy. Konstruktor jest automatycznie wołany gdy tworzony jest nowy obiekt. Nazwa konstruktora jest taka jak nazwa klasy do której należy Jeśli nie zdefiniuje się żadnego konstruktora to dodawany jest automatycznie domyślny konstruktor bezparametrowy
Przykład: Konstruktor class Kwadrat { Kwadrat() { System.out.println( Konstruktor klasy Kwadrat ); public class TestKonstruktora1 { public static void main(string[] args) { for(int i = 0; i < 10; i++) new Kwadrat();
Konstruktor Przykład 2: class Kwadrat { Kwadrat(int b) { System.out.println( Ctor klasy Kwadrat o boku + b); public class TestKonstruktora2 { public static void main(string[] args) { for(int i = 0; i < 10; i++) new Kwadrat(i);
Konstruktor Przykład 3: class Kwadrat { Kwadrat() { System.out.println( Konstruktor klasy Kwadrat ); Kwadrat(int b) { System.out.println( Ctor klasy Kwadrat o boku + b);
Przykład 3 cd: public class TestKonstruktora3 { Konstruktor public static void main(string[] args) { for(int i = 0; i < 10; i++) { if( i % 3!= 0 ) { new Kwadrat(i); else { new Kwadrat();
Przeciążanie funkcji w klasie W ramach jednej klasy nie może być dwóch metod o takich samych nazwach i odbieranych parametrach. Mogą natomiast istnieć dwie metody o takich samych nazwach ale różniące się odbieranymi parametrami decyzja, której z nich użyć jest podejmowana na podstawie parametrów.
Przeciążanie funkcji w klasie cd. Przykład: class P { void foo() { System.out.println( Foo wersja 1 ); void foo(int i) { System.out.println( Foo wersja 2 ); void foo(string s) { System.out.println( Foo wersja 3 );
Przeciążanie funkcji w klasie cd. Przykład cd.: public class TestPrzeciazania { public static void main(string[] args) { P p1 = new P(); p.foo(); // wersja 1 p.foo(10); // wersja 2 p.foo( Test ); // wersja 3
Słowo kluczowe this Słowo kluczowe this może być używane tylko wewnątrz niestatycznych metod klasy i oznacza bieżący obiekt na którym wykonywana jest metoda. Przykład: class X { void f(int i) { /*...*/ X a = new X(), b = new X(); a.f(1); b.f(2); Funkcja f musi wiedzieć na którym obiekcie klasy X ma operować jest to możliwe dzięki przekazaniu do niej ukrytej referencji do obiektu jako pierwszego argumentu.
Słowo kluczowe this cd. Ponieważ referencja do obiektu jest ukryta nie ma do niej normalnego dostępu, jednak właśnie słowo kluczowe this zapewnia ten dostęp. Normalnie nie ma potrzeby używania słowa kluczowego this. Przykład: class Y { void f1() { /*... */ void f2() { f1(); /*... */ void f3() { this.f1(); /*... */
Przykład 2: class Z { int i = 0; Słowo kluczowe this cd. Z zwieksz() { i++; return this; void print() { System.out.println( i= + i); public static void main(string[] args) { Z a = new Z(); a.zwieksz().zwieksz().zwieksz().print();
Wywołanie konstruktora z innego konstruktora Przykład: class Prostokat { int boka = 0; int bokb = 0; Prostokat(int a, int b) { boka = a; bokb = b; //...
Wywołanie konstruktora z innego konstruktora cd. //... Prostokat(int a) { this(a,a); Prostokat() { this(10,10); //! this(10); // nie można wolac dwa razy
Niszczenie obiektów metoda finalize() Metoda finalize() jest wołana przez garbage collector w momencie gdy obiekt ma zostać usunięty Nie należy jej wywoływać samodzielnie Nie ma gwarancji, że zostanie ona zawołana Jej użycie powinno być ograniczone do zwolnienia pamięci zaalokowanej poza mechanizmami Javy
Niszczenie obiektów Do posprzątania po obiekcie należy zaimplementować własną metodę, którą następnie należy ręcznie wywołać, gdy obiekt jest już niepotrzebny.
Inicjalizacja zmiennych Java nie gwarantuje, że stworzona zmienna jest poprawnie zainicjalizowana. W przypadku gdy wystąpi próba odwołania do niezainicjalizowanej zmiennej, podczas kompilacji zostanie zgłoszony błąd. Przykład: void foo() { int i; i++;
Inicjalizacja składowych obiektu Gdy składowymi klasy są typy proste to Java domyślnie je inicjalizuje: class Wartosci { boolean t; // domyslna war. false char c; // domyslna war. \0 byte b; // domyslna war. 0 short s; // domyslna war. 0 int i; // domyslna war. 0 long l; // domyslna war. 0 float f; // domyslna war. 0.0 double d; // domyslna war. 0.0 //...
Inicjalizacja składowych obiektu Gdy składowymi klasy są referencje do obiektów to domyślnie Java nadaje im wartość null (jest to słowo kluczowe Javy).
Inicjalizacja składowych obiektu W Javie można do składowych przypisać wartość początkową inną niż wartość domyślna: class Wartosci { boolean t = true; char c = q ; byte b = 10; short s = 0xaa; int i = 555; long l = 23; float f = 3.14f; double d = 3.141592; Kwadrat k = new Kwadrat(); // inicjalizacja referencji
Inicjalizacja składowych obiektu Można też zawołać funkcje w celu inicjalizacji zmiennej: class Inicjalizacja { int i = f(); Można wołać też funkcje z parametrami, ale parametrami nie mogą być niezainicjalizowane zmienne: class Inicjalizacja { //! j = g(i); // blad i nie jest zainicjalizowane int i = f(); int j = g(i); // ok. i jest już zainicjalizowane
Definicja tablicy: int[] t1; lub Inicjalizacja tablic int t1[]; // definicja w stylu C Inicjalizacja tablicy: int t1[] = { 1, 5, 6, 13 ; Możliwe jest też przypisanie jednej tablicy do drugiej, jest to przypisanie referencji: int[] t2; t2 = t1;
Inicjalizacja tablic cd. Przykład: public class Tablice { public static void main(string[] args) { int[] t1 = { 1, 2, 5, 8, 12 ; int[] t2; t2 = t1; for(int i = 0; i < t2.length; i++) t2[i]++; for(int i = 0; i < t1.length; i++) System.out.println( t1[ + i + ] = + t1[i] );
Inicjalizacja tablic cd. Możliwe jest też określenie rozmiaru inicjalizowanej tablicy: int[] t = new int[54]; Dla typów obiektowych oprócz zainicjalizowania samej tablicy, trzeba też inicjalizować każdy element tej tablicy: Integer[] t = new Integer[20]; // inicjalizacja tablicy for(int i = 0; i < t.length; i++ ) { t[i] = new Integer(0); // inicjalizacja elementow
Tablice wielowymiarowe Java pozwala na łatwy sposób tworzenia tablic wielowymiarowych: int[][] t1 = { { 1, 2, 3, { 4, 5, 6, ; for(int i = 0; i < t1.length; i++) for(int j = 0; j < t1[i].length; j++) System.out.println( t1[ + i + ][ + j + ] = + t1[i][j]); //...
Tablice wielowymiarowe cd. Tworzenie tablic wielowymiarowych o określonym rozmiarze: int[][][] t2 = new int[2][2][5];
Specyfikacja dostępu
Dostęp do składowych klasy Jeśli nie ma określonego specyfikatora dostępu to jako domyślny przyjmowany jest friend, który oznacza możliwość dostępu w ramach tego samego pakietu (pliku).dostęp w ramach pakietu Specyfikator public oznacza, że wszyscy mają dostęp do składowej Specyfikator private dopuszcza dostęp do składowej tylko w ramach tej samej klasy Specyfikator protected dopuszcza dostęp do składowej tylko w ramach tej samej klasy i klas z niej dziedziczących
Dostęp do składowych klasy Przykład: public class X { public void pub1() { /*... */ public void pub2() { /*... */ private void priv1() { /*... */ protected void prot1() { /*... */ private int i;
Dziedziczenie W Javie możliwe jest tylko dziedziczenie pojedyncze Wszystkie obiekty w Javie dziedziczą z obiektu podstawowego Objects Do oznaczenia dziedziczenia służy słowo kluczowe extends
Dziedziczenie Przykład: class A { private String s = new String( Klasa A ); public void append(string str) { s += str; public void foo1() { append( foo1() ); public void foo2() { append( foo2() ); public void print() { System.out.println(s); public static void main(string[] args) { A obiekt1 = new A(); obiekt1.foo1(); obiekt1.foo2(); obiekt1.print();
Dziedziczenie Przykład cd: public class B extends A { public void foo2() { append( B.foo2() ); super.foo2(); // wywolanie metody klasy bazowej public void foo3() { append( foo3() ); public static void main(string[] args) { B obiekt = new B(); obiekt.foo1(); obiekt.foo2(); obiekt.foo3(); A.main(args); // test klasy bazowej