Wykład Java ver3.0 1

Wielkość: px
Rozpocząć pokaz od strony:

Download "Wykład Java 07-01-31 ver3.0 1"

Transkrypt

1 Wykład Java ver3.0 1 Java jest językiem stosowanym w Internecie. Aby zrozumieć jego ważność, można przyjąć, że ma on tak samo duże znaczenie dla programowania w Internecie, jak C++ dla programowania systemowego.. Bez Javy nie istniałby Internet w obecnym kształcie. Język Java został opracowany w 1991 roku przez Jamesa Goslinga, Patricka Naughtona, Chrisa Wartha, Eda Franka i Mike'a Sheridana z firmy Sun Microsystems, Inc. Utworzenie pierwszej działającej wersji zajęło dalszych 18 miesięcy. Język ten początkowo nazywał się Oak (dąb), ale w 1995 roku jego nazwę zmieniono na Javę. W okresie dzielącym pojawienie się pierwszej implementacji języka Oak na jesieni 1992 roku i oficjalnego ogłoszenia powstania Javy na wiosnę 1995 roku wiele osób przyczyniło się do ulepszenia rozwiązań i rozwoju tego języka. Głównymi sprawcami udoskonalania początkowej wersji byli: Bill Joy, Arthur van Hoff, Jonathan Payne, Frank Yellin i Tim Lindholm. Może się to wydawać dziwne, ale początkowo język Java nie był przeznaczony dla, Internetu. U podstaw jego utworzenia była potrzeba istnienia języka niezależnego od mikroprocesora i systemu operacyjnego, którego można by używać do tworzenia oprogramowania instalowanego w różnych elektronicznych urządzeniach, takich jak kuchenki mikrofalowe i urządzenia zdalnego sterowania. Java została początkowo zaprojektowana jako narzędzie do tworzenia przenośnego kodu, który dawałby się uruchamiać w różnego rodzaju urządzeniach sterujących. W czasie opracowywania szczegółów Javy pojawiał się stopniowo drugi i o wiele ważniejszy czynnik, który odegrał kluczową rolę w dalszym rozwoju tego języka. Czynnikiem tym była oczywiście sieć WWW. W tej dziedzinie był także potrzebny środek tworzenia przenośnego kodu. Gdyby strony WWW nie nabrały tak ogromnego znaczenia w czasie projektowania Javy, to prawdopodobnie pozostałaby ona użytecznym wprawdzie, ale mało znanym językiem programowania, używanym przy projektowaniu konsumenckich urządzeń elektronicznych. Jednak w miarę rozrastania się sieci WWW Java wysuwała się na pierwsze miejsce w dziedzinie projektowania języków komputerowych. Java jest spokrewniona z C++ z dwóch ważnych powodów. Po pierwsze, używa tej samej składni: taką samą postać mają takie instrukcje, jak for, while czy do. Po drugie, w obu językach stosowane są bardzo podobne zasady projektowania zorientowanego obiektowo. Z powodu powierzchownych podobieństw występujących między językami C++ i Java można przypuszczać, że Java jest wersją Internetową języka C++. Stwierdzenie to nie jest jednak w pełni prawdziwe, ponieważ między obu językami istnieją również różnice, zmieniające w istotny sposób ich charakter. Mimo to programiści C++ nie mają powodów do zmartwienia: nauka programowania w Javie nie przysporzy im z pewnością problemów.

2 Wykład Java ver3.0 2 Podsumowując, można stwierdzić, że przewaga Javy nad C++ wynika nie z tego, co ten nowy język zawiera, ale raczej, czego nie zawiera. 1 Najważniejsze zalety Javy: Ponieważ języki C i C++ są wszechstronnymi, dobrze zdefiniowanymi, profesjonalnymi językami programowania, można by się zastanawiać nad sensownością wprowadzenia jeszcze jednego języka. Jednak utworzenie Javy było konieczne z dwóch ważnych powodów, które dają się streścić za pomocą dwóch słów: bezpieczeństwo i przenośność. Bezpieczeństwo Z pewnością wszyscy programiści wiedzą, że załadowanie każdego "zwykłego" programu wiąże się z ryzykiem zarażenia komputera wirusem. Przed wprowadzeniem Javy większość użytkowników sieci nie pobierało zbyt często wykonywalnych programów, a jeżeli to robili, to przed ich uruchomieniem testowali je programami antywirusowymi. Jednak nawet wówczas nie znikało w pełni ryzyko zarażenia systemu lub uruchomienia "złośliwego" programu (program taki mógł zbierać informacje poufne, takie jak numery kart kredytowych, stany kont bankowych czy hasła, przeszukując zawartość lokalnego systemu plików). Odpowiedzią Javy na te zagrożenia było wprowadzenie "zapory ogniowej" (ang. firewall, istniejącej między aplikacją sieciową a komputerem lokalnym. Korzystając z przeglądarki WWW kompatybilnej z Javą, można bezpiecznie wczytywać aplety Javy bez obawy o zarażenie komputera wirusem. Twórcy Javy uzyskali to przez ograniczenie zakresu instrukcji tego języka do środowiska wykonywania danego programu i uniemożliwienie dostępu do innych elementów komputera (wkrótce zostanie objaśniony sposób zrealizowania tego celu). Mówiąc krótko, najważniejszą cechą charakterystyczną Javy jest możliwość ładowania apletów, mając pewność, że nie wyrządzą one żadnej szkody komputerowi użytkownika sieci. Przenośność Istnieje wiele różnych typów komputerów i systemów operacyjnych - wiele z nich jest podłączonych do Internetu. Aby programy można było dynamicznie ładować i uruchamiać we wszystkich systemach komputerowych połączonych z siecią WWW, trzeba dysponować narzędziem pozwalającym generować przenośny kod wykonywalny. Jak będzie się można wkrótce przekonać, sposób, w jaki Java pozwala uzyskać przenośność, jest zarówno elegancki, jak i efektywny 1 Partrick Naughton

3 Wykład Java ver3.0 3 Istota kodu bajtowego Wiele problemów można rozwiązać dzięki temu, że kompilator Javy nie tworzy kodu wykonywalnego programów, lecz tak zwany kod bajtowy (ang. bytecode). Kod bajtowy jest wysoko zoptymalizowanym zestawem instrukcji przeznaczonym do wykonywania przez maszynę wirtualną, którą emuluje system czasu przebiegu Javy. Można więc powiedzieć, system czasu przebiegu Javy (ang. Java run-time system) jest interpreterem kodu bajtowego. Może się to wydawać dziwne, gdyż -jak wiadomo - programy C++ są kompilowane do postaci kodu wykonywalnego. Zresztą większość współczesnych języków programowania jest przeznaczonych do kompilowania, a nie interpretowania, głównie ze względu na szybkość wykonywania programów. Jednak fakt, że programy Javy są interpretowane, pozwala rozwiązać główne problemy związane z ładowaniem programów z Internetu. Jest tak dlatego, że interpretowanie kodu bajtowego Javy ułatwia uruchamianie programów Javy w wielu różnych środowiskach. Przyczyna tego jest oczywista: dla każdej platformy trzeba zaimplementować jedynie system czasu przebiegu Javy. Kiedy już pakiet ten istnieje w danym systemie komputerowym, można go używać do uruchamiania wszystkich programów Javy. Należy pamiętać, że szczegóły systemu czasu przebiegu Javy zależą od danej platformy, to jednak wszystkie potrafią interpretować ten sam kod bajtowy tego języka. Gdyby programy Javy były kompilowane, to należałoby tworzyć różne wersje wykonywalne tego samego programu, przeznaczone dla poszczególnych rodzajów komputerów połączonych z Internetem. Nie byłoby to oczywiście rozwiązaniem dającym się zrealizować w praktyce. Jak więc widać, interpretacja jest najłatwiejszym sposobem tworzenia w pełni przenośnych programów. Fakt, że programy Javy są interpretowane, pomaga także uczynić je bezpiecznymi. Ponieważ wykonywaniem każdego programu steruje w pełni system czasu przebiegu Javy, może on ograniczać wykonywane przez niego operacje i uniemożliwić mu wywoływanie efektów ubocznych. Jak będzie się można przekonać, bezpieczeństwo dodatkowo się zwiększa przez wprowadzenie niektórych ograniczeń dotyczących Javy. Jak zapewne niektórzy czytelnicy wiedzą, programy, które są interpretowane, działają znacznie wolniej, niż ich odpowiedniki kompilowane do postaci kodu wykonywalnego. Jednak w przypadku Javy wydłużenie czasu wykonywania programów nie jest duże. Stosowanie kodu bajtowego umożliwia bowiem systemowi czasu przebiegu Javy wykonywanie programów dużo szybciej niż można by tego oczekiwać. Nie oznacza to rezygnacji z bezpieczeństwa i przenośności programów, gdyż również w takiej sytuacji ich wykonywaniem zarządza system czasu przebiegu Javy

4 Wykład Java ver3.0 4 Podobieństwo do języka C/C++ Java została zaprojektowana w taki sposób, aby zawodowi programiści mogli się jej szybko nauczyć i efektywnie stosować. Dotyczy to szczególnie programistów C++, gdyż rozpoczęcie programowania w Javie wymaga od nich minimalnego wysiłku. Ponieważ w Javie jest stosowana składnia języków C/C++ i wiele elementów programowania zorientowanego obiektowo, większość programistów jest w stanie poznać ten język w bardzo krótkim czasie. Jest tak również dlatego, że najgorsze rozwiązania stosowane w C/C++ zostały w Javie poprawione lub nie zostały do niej przeniesione. Zorientowanie obiektowe Projektanci Javy ulepszyli koncepcje programowania zorientowanego obiektowo istniejących języków programowania, takich jak C++. Nie musieli jednak kopiować ich wad, gdyż mieli możliwość utworzenia od początku takiego modelu obiektów, który byłby przejrzysty i łatwy w stosowaniu. Mimo iż Java jest językiem ze ścisłą kontrolą obiektów, to jednak umożliwia pisanie szybko działających programów. Przyczynia się do tego między innymi fakt, że podstawowe typy, takie jak liczby całkowite czy znaki, są typami elementarnymi, a nie obiektami. Wygoda Kilka cech charakterystycznych Javy pozwala pisać w prosty sposób poprawnie działające i funkcjonalne programy. Po pierwsze, jest to język ze ścisłą kontrolą typów. Ponieważ dla każdej zmiennej i wyrażenia trzeba określić typ, pozwala to wykrywać ewentualne błędy już w czasie kompilowania programu. Wszelkiego rodzaju niezgodności typów są sygnalizowane w postaci komunikatów kompilatora. Po drugie, w Javie jest dużo łatwiej zarządzać pamięcią, niż w C++, gdyż nie trzeba pisać instrukcji zwalniających przydzieloną pamięć (nieużywane fragmenty pamięci są zwalniane automatycznie). Po trzecie, zorientowana obiektowo obsługa wyjątków umożliwia utworzenie przejrzystej struktury tekstu źródłowego, ułatwiającej wykrywanie sytuacji nietypowych pojawiających się podczas działania programu i odpowiednie reagowanie. Wielowątkowość Projektanci Javy uwzględnili potrzebę istnienia języka umożliwiającego tworzenie praktycznie wykorzystywanych, interaktywnych programów sieciowych. Dlatego Java pozwala pisać programy wielowątkowe, a więc wykonujące jednocześnie wiele operacji. W systemach czasu przebiegu Javy zastosowano eleganckie, choć skomplikowane rozwiązanie synchronizacji procesów, umożliwiające konstruowanie sprawnie działających programów interaktywnych.

5 Wykład Java ver3.0 5 Łatwość stosowania wielowątkowości w Javie pozwala myśleć kategoriami działania programu, a nie realizacji wielozadaniowości. Niezależność od sprzętu Jednym z głównych osiągnięć zespołu pracującego nad Javą jest umożliwienie tworzenia. pojedynczych wersji programów, które można uruchamiać w wielu różnych systemach komputerowych. Wymaga to oczywiście instalowania maszyny wirtualnej Javy w nowo powstającym sprzęcie i oprogramowaniu. Dzięki temu kod bajtowy generowany na podstawie tekstu źródłowego Javy może pozostawać cały czas niezmienny. Interpretacja Wadą języków interpretowanych jest często niezadowalająca szybkość działania programów. Jest to szczególnie dotkliwe podczas korzystania z wolno działających procesorów. Istnieje jednak możliwość bieżącej (ang. just-in-time) kompilacji programów. Oznacza to, że kod bajtowy wygenerowany przez kompilator Javy jest tłumaczony na kod wykonywalny, właściwy dla danego procesora, tuż przed jego pierwszym wykonaniem. Instrukcje kodu bajtowego zostały zaprojektowane w taki sposób, aby to tłumaczenie przebiegało jak najsprawniej. Poza tym kod bajtowy jest optymalizowany ze względu na jego interpretację, tak więc problemy towarzyszące zwykle korzystaniu z języków interpretowanych nie są w przypadku Javy znaczące. Środowisko rozproszone Java została zaprojektowana dla środowiska rozproszonego Internetu, ponieważ umożliwia ona korzystanie z protokołów TCP/IP. Uzyskanie dostępu do zasobu przez podanie adresu URL (skrót od ang. Uniform Resource Locator = ujednolicony adres zasobu) jest niewiele trudniejsze niż uzyskanie dostępu do pliku. Dynamika Programy Javy zawierają znaczne ilości informacji czasu przebiegu dotyczących typów i wykorzystywanych w celu weryfikowania i realizowania żądań dostępu do obiektów. Umożliwia to dynamiczne dołączanie kodu w łatwy i wygodny sposób. Jest to bardzo ważne dla sprawnego funkcjonowania środowiska apletów, gdzie małe fragmenty kodu bajtowego mogą być dynamicznie uaktualniane w działających programach.

6 Wykład Java ver3.0 6 Różnice między Javą i C++ Mimo iż pierwowzorem Javy jest C++, to jednak między tymi językami istnieje kilka podstawowych różnic. Niektóre z nich polegają tylko na wprowadzeniu drobnych zmian, inne są związane z głównymi założeniami projektu, mającymi istotny wpływ na sposób pisania programów. W dalszej części wykładu zostaną omówione najważniejsze różnice. Wcześniej jednak musimy sobie zdać sprawę z pewnego, bardzo ważnego faktu: Java została zaprojektowana w celu umożliwienia bezpiecznego ładowania przenośnych aplikacji za pomocą sieci i w swoim obecnym kształcie nie można nią zastąpić języków C/C++ jako narzędzi do tworzenia programów systemowych. Pamiętając o tym, przyjrzyjmy się kilku różnicom występującym między językami Java oraz C++. Elementy usunięte z C/C++ Kilka elementów charakterystycznych języka C++ nie zostało przeniesionych do Javy. Część z nich po prostu nie odnosiła się do środowiska programów Javy. Projektanci Javy usuwali także te elementy języka C++, które były w nim powielane. W jeszcze innych przypadkach nie zostały uwzględnione elementy programowania, które byłyby zbyt niebezpieczne w apletach Javy. Prawdopodobnie największą różnicą występującą między językami C/C++ i Java jest brak wskaźników w tym ostatnim. Jako programiści C/C++, wszyscy czytelnicy wiedzą, że wskaźniki są najważniejszymi i najbardziej wszechstronnymi elementami języków programowania. Jednak w przypadku ich niewłaściwego użycia stają się one bardzo niebezpieczne. Wskaźniki nie istnieją w Javie z dwóch powodów. Przede wszystkim właśnie dlatego, że ich stosowanie wiąże się z dużym niebezpieczeństwem. Na przykład korzystając ze wskaźników C++ można uzyskać dostęp do komórek pamięci znajdujących się poza miejscem zajmowanym przez kod wynikowy i dane programu. "Złośliwy" program mógłby wykorzystać ten fakt w celu zniszczenia systemu, uzyskanie niedozwolonego dostępu do jego zasobów (na przykład odczytania haseł) lub wykonania innego działania niezgodnego z zasadami bezpieczeństwa. Po drugie, nawet jeśli zakres wskaźników byłby ograniczony przez system czasu przebiegu Javy (co byłoby teoretycznie możliwe, gdy programy Javy są interpretowane), to i tak twórcy tego języka uznali, że są one częstym źródłem występowania błędów w programach. Z faktu, że Java nie zawiera wskaźników, wynika, że nie istnieje w niej także operator ->. Java nie zawiera struktur i unii. Zostały one uznane jako zbędne, gdyż można je zastąpić klasami.

7 Wykład Java ver3.0 7 W Javie nie jest możliwe przeładowywanie operatorów. Ponieważ działanie to jest często źródłem wieloznaczności w programach C++, projektanci Javy stwierdzili, iż przynosi ono więcej kłopotów niż korzyści. Java nie zawiera preprocesora i nie umożliwia stosowania jego dyrektyw, twórcy Javy postanowili w ogóle z nich zrezygnować. W Javie nie są wykonywane automatyczne konwersje typów powodujące zmniejszenie dokładności. Na przykład przekształcenie typu long int w int musi być dokonane jawnie. Cały tekst źródłowy programu Javy należy do jednej lub większej liczby klas. W związku z tym w Javie nie istnieje pojęcie funkcji i zmiennych globalnych. Java nie pozwala na stosowanie argumentów domyślnych. W C++ można określić wartość, która jest automatycznie przypisywana parametrowi w przypadku pominięcia odpowiadającego mu argumentu w wywołaniu funkcji. W Javie nie jest to dozwolone. Java nie pozwala na dziedziczenie wielu klas przez pojedynczą klasę pochodną. W Javie istnieją konstruktory, ale nie ma destruktorów. Zamiast nich została wprowadzona funkcja finalize(). Java nie zawiera instrukcji typedef. Nie można deklarować liczb całkowitych bez znaku (unsigned int). W Javie nie istnieje instrukcja goto. Nie ma operatora delete. Operatory <<i >> nie zostały przeładowane do celów operacji wejścia/wyjścia. W Javie obiekty można przekazywać wyłącznie przez odwołanie (w C++ obiekty mogą być przekazywane zarówno przez odwołanie, jak i przez wartość). Nowe elementy dodane do Javy Niektóre elementy Javy nie mają swoich odpowiedników w C++. Do najważniejszych z nich z pewnością należą pakiety, interfejsy i wielowątkowość. Oprócz nich istnieje kilka innych, wzbogacających środowisko programowania Javy. Pakiet (ang. package) definiuje w Javie obszar nazw i umożliwia grupowanie spokrewnionych ze sobą klas. Nie ma elementów C++, które by bezpośrednio odpowiadały pakietom Javy. Najbliższe podobieństwo do nich wykazuje zestaw funkcji bibliotecznych korzystających ze wspólnego pliku nagłówkowego. Jednak konstruowanie i korzystanie z biblioteki C++ przebiega zupełnie inaczej niż konstruowanie i korzystanie z pakietów Javy. Interfejs (ang. interface) Javy przypomina w pewnym stopniu klasę abstrakcyjną C++ (klasa abstrakcyjna C++ jest klasą zawierającą przynajmniej jedną funkcję wirtualną). Na przykład oba elementy językowe służą do określania wspólnego interfejsu implementowanego przez klasy pochodne, stąd też nie jest dozwolone tworzenie ich obiektów. Główna różnica między

8 Wykład Java ver3.0 8 klasami abstrakcyjnymi a interfejsami Javy polega na tym, że te ostatnie lepiej służą idei tworzenia dziedziczonych klas wzorcowych. Wielowątkowość umożliwia jednoczesne wykonywanie dwóch lub większej liczby fragmentów tego samego programu. Rozwiązanie zastosowane w Javie pozwala na uzyskiwanie wielowątkowości za pomocą wbudowanych mechanizmów. Nie istnieje odpowiednik tego elementu w języku C++. Jeżeli program C++ ma składać się z wielu wątków, to można ten cel osiągnąć jedynie "ręcznie", za pomocą funkcji systemu operacyjnego. Mimo iż obie metody umożliwiają jednoczesne wykonywanie wielu wątków, to jednak rozwiązanie zastosowane w Javie jest bardziej przejrzyste i łatwiejsze w stosowaniu. innym elementem różniącym Javę od C++ jest sposób przydziału pamięci. Podobnie jak w C++, w Javie istnieje słowo kluczowe new, ale nie ma słowa delete. Jest to spowodowane tym, że zniszczenie ostatniego odwołania do danego obiektu powoduje jego automatyczne usunięcie podczas wykonywania następnej operacji porządkowania pamięci (ang. garbage collection). W Javie została usunięta biblioteka standardowa C/C++, a zastąpił ją specjalny zestaw klas API. Między obu rodzajami funkcji istnieje znaczne podobieństwo, ale występują też istotne różnice w nazewnictwie parametrów. Poza tym, ponieważ cała biblioteka API Javy jest zorientowana obiektowo, w przeciwieństwie do biblioteki C++, która jest zorientowana obiektowo tylko w części, w odmienny sposób wywołuje się oba rodzaje funkcji bibliotecznych. Rozszerzono zakres stosowania instrukcji break i continue, umożliwiając stosowanie etykiet jako wartości docelowych. Typ char oznacza 16-bitowe znaki zapisywane w ujednoliconym kodzie Unicode. Stosowanie ujednoliconego kodu jest gwarantem uzyskania przenośności. Java posiada operator >>>, wykonujący przesunięcie w prawo liczby bez znaku. Oprócz komentarzy jednowierszowych (//) i wielowierszowych (/* */) w Javie można stosować również komentarze dokumentacyjne, które rozpoczynają się od znaków /** i kończą znakami */. Java zawiera wbudowany typ łańcuchowy o nazwie String. Jest on nieco podobny do standardowej klasy string języka C++. Oczywiście klasa string nie jest typem wbudowanym, dlatego można z niej korzystać dopiero po dołączeniu do programu odpowiedniego pliku nagłówkowego. Zmienione elementy

9 Wykład Java ver3.0 9 Istnieją elementy, które istnieją zarówno w C++, jak i Javie, ale w każdym z tych języków funkcjonują nieco inaczej. W obu językach istnieje typ danych logicznych, ale różna jest implementacja wartości true i false. W C++ true jest dowolną wartością różną od zera, a false zerem, natomiast w Javie true i false są predefiniowanymi literałami, określającymi jedyne dopuszczalne wartości wyrażeń typu boolean. Wprawdzie także w C++ są zdefiniowane wartości true i false, które można przypisywać zmiennym typu boolean, ale wszystkie wartości niezerowe są w razie potrzeby automatycznie przekształcane w true, a wartości zerowe w false. W Javie operacja taka nie jest wykonywana. Specyfikatory dostępu zamieszczone w definicji klasy C++ dotyczą grup instrukcji, natomiast w Javie wyłącznie deklaracji, które bezpośrednio poprzedzają. W programach C++ można obsługiwać wyjątki podobnie, jak w programach Javy. Jednak w C++ nie ma obowiązku przechwytywania wszystkich generowanych wyjątków, podczas gdy w Javie większość wyjątków musi być przechwytywana. Z Javą wiążą się dwa ważne terminy, nie używane w językach programowania C/C++: aplety i metody. Aplety Javy Za pomocą Javy można tworzyć dwa rodzaje programów: aplikacje i aplety. Aplikacja jest programem działającym na komputerze użytkownika i zarządzanym przez jego system operacyjny. Tak więc Java jest (w większym lub mniejszym stopniu) podobna do aplikacji utworzonej przez kompilator C lub C++. Jeżeli Javy używa się do przygotowywania aplikacji, to nie różni się ona wiele od innych języków programowania. Cechą Javy, która nadaje jej znaczenia, jest możliwość tworzenia apletów. Aplet (ang. applet) jest małą aplikacją przeznaczoną do przesłania jej za pomocą Internetu i wykonywaną za pomocą kompatybilnej z Javą przeglądarki sieci WWW. Dzięki stosowaniu apletów zawartość strony WWW może aktywnie decydować o sposobie jej wyświetlenia. Możliwość tworzenia przenośnych, dynamicznie ładowalnych apletów jest najważniejszą przyczyną ogromnej popularności Javy. Metody Zanim przejdziemy do pisania pierwszej aplikacji Javy, musi zostać wyjaśniony jeszcze jeden ważny termin używany przez programistów Javy. W języku tym bardzo rzadko pojawia się

10 Wykład Java ver termin funkcja. Fragment programu, który programista C++ nazwałby funkcją składową, jego kolega programujący w Javie nazywa metodą (ang. method). Wynika to stąd, że w Javie nie istnieją funkcje globalne. Wszystkie funkcje (metody) należą do klas.

11 Wykład Java ver Termin API AFC AWT BDK Enterprise APIs HotJava IFC Internacjonalizacja Wybrane terminy związane z Javą Znaczenie Application Programming Interfaces; standard programowania (taki jak stdlib lub Win32) Application Foundation Classes: biblioteka klas wypromowana przez Microsoft. Zobacz także IFC, JFC Abstract Window Toolkit: biblioteka GUI Javy Beans Development Kits. Zobacz także JDK, Java Beans "Enterprise APIs" firmy Sun dla Javy z JDBC, RMI i Security Kompletna przeglądarka WWW napisana w całości w Javie Internet Foundation Classes: biblioteka klas promowana przez Netscape. Zobacz także AFC, JFC Program do obsługi różnych języków (na przykład francuskiego lub angielskiego) i różnych miejsc (na przykład Wielka Brytania a symbole walut i pisownia amerykańska) bez ponownej kompilacji. Java 1.1 wprowadza nowe właściwości, które upraszczają internacjonalizację. Zobacz także Unikod, ResourceBundles Introspekcja Oznacza, według którego klienta można "otrzymać" funkcjonalność wyeksportowaną przez Java Bean. Zobacz także Java Beans, Refleksja JAR Java Beans JavaOS JDK JFC JIT JNI JDBC JVM Właściwości Plik Java Archive: wygodne środki do wczytywania apletu i innych związanych plików (pliki dźwiękowe, obrazy, pomoc itd.) za jednym "zamachem", zamiast przez kilka osobnych zapytań HTTPD "Software component model"; podobne do COM i ActiveX Microsoftu System operacyjny rozwinięty przez Sun, nadający się szczególnie do uruchamiania aplikacji Javy Java Development Kit: kompletny kompilator Javy, biblioteki itd.jdk można otrzymać za darmo ze strony początkowej firmy Sun Java Foundation Classes: biblioteka klas Javy firmy Sun. Zobacz także AFC, IFC Just In Time Compiler. JIT przekształca ("od ręki") kody bajtowe Javy na wykonywalne. Użycie JIT w przeglądarkach WWW drastycznie zwiększyło wydajność programów Javy Native Method Interface: umożliwia programom C używanie klas i metod Javy Java Data Base Connectivity: część Enterprise API. JDBC umożliwia programom Javy komunikowanie się z bazami danych; podobne do ODBC Microsoftu Java vrtualmachine: interpretuje kod bajtowy Javy i wykonuje program Javy (na przykład w przeglądarce z aktywną Javą) Java Beans eksportuje swoje właściwości do programów klienta jako zestaw wlaściwości (atrybuty obiektu) i metody (zachowanie)

12 Wykład Java ver Termin Refleksja ResourceBundle RMI Servlet Sygnowany aplet Unikod Wybrane terminy związane z Javą Znaczenie To nowy pakiet JDK 1.1 umożliwiający uzyskanie informacji o właściwościach i metodach dostępnych w elemencie Java Bean "Refleksja" jest podobna do "Bibiotek typu" używanych w MS- Windows Związane z internacjonalizacją. Zwykle polega na zdefiniowaniu unikatowej "wiązki" Remote Method Invocation: część Enterprise API; umożliwia apletom Javy wywołanie zdalnych zasobów (na przykład innych aplętów) w różnych procesach lub nawet na różnych maszynachw Internecie Program Javy przeznaczony do uruchamiania na serwerze WW W; przeciwieństwo apletu, który jest wczytywany i uruchamiany na kliencie Dołączenie "podpisu cyfrowego" do pliku JAR Javy gwarantuje,że aplet pochodzi z dobrego źródła Format łańcucha w Javie; przeznaczony do obsługi dowolnego znaku w dowolnym języku Słowa kluczowe Zarezerwowane słowa kluczowe są specjalnymi identyfikatorami umożliwiającymi zapisywanie programów. Służą one wyłącznie do identyfikowania wbudowanych typów, modyfikatorów i instrukcji sterujących, nie można więc ich używać na przykład jako nazw zmiennych czy metod. W połączeniu z operatorami i separatorami, słowa kluczowe umożliwiają zdefiniowanie pełnej składni Javy. W sumie język ten (w wersji 1.0) zawiera 59 słów kluczowych, zamieszczonych w tabeli Zarezerwowane słowa kluczowe abstract break byte byvalue case cast catch char class const continue default do double else extends false final finally float for future generic goto if implements import inner instanceof int interface long native new null boolean operator outer package private protected public rest return short static super switch synchronized this throw throws transient true try var void volatile while Identyfikatory

13 Wykład Java ver Identyfikatorów używa się jako nazw klas, metod i zmiennych. Mogą one składać się z liter, cyfr, znaku podkreślenia i znaku dolara. Pierwszy znak nie może być cyfrą, gdyż w przeciwnym razie można by je było pomylić z omówionymi niżej literałami numerycznymi. W Javie są rozróżniane małe i duże litery, na przykład identyfikatory DOM i Dom są różne. Do poprawnie zbudowanych identyfikatorów należą między innymi: timeofday, temp_val, a4 i $_. Natomiast niepoprawne identyfikatory to na przykład 1more, 3$, #abc Twórcy Javy proponują, aby wszystkim metodom i zmiennym publicznym przydzielać identyfikatory rozpoczynające się od małych liter i zawierające duże litery na początku każdego nowego słowa, na przykład nextltem, currentvalue czy gettimeofday. Natomiast identyfikatory metod prywatnych oraz zmiennych prywatnych i lokalnych powinny zawierać wyłącznie małe litery oraz znaki podkreślenia oddzielające kolejne wyrazy, na przykład next_val czy temp_val. Zmienne finalne, czyli zmienne o stałych wartościach, najlepiej jest wyróżniać za pomocą dużych liter, na przykład TOK_BRACE, DAY_FRIDAY czy GREEN. Literały Stałe wartości zapisuje się w programach Javy w postaci literałów. Z każdym literałem jest związany określony typ, czyli sposób zapisywania go i wykonywania na nim operacji - może to być liczba całkowita, liczba zmiennoprzecinkowa (rzeczywista), wartość logiczna (boolowska), znak lub łańcuch (tekst). Literały całkowite Literały całkowite są najczęściej występującymi literałami w większości programów. Umożliwiają one zapisywanie liczb całkowitych w trzech systemach liczenia: dziesiętnym, ósemkowym i szesnastkowym. Literały ósemkowe (oktalne), używane przez niektórych doświadczonych programistów, umożliwiają zapisywanie cyfr odpowiadających trójkom bitów, ale korzyści wynikające z ich stosowania są niewielkie. Mogą one zawierać wyłącznie cyfry od 0 do 7 i muszą zaczynać się od 0. Wynika stąd, że pozornie prawidłowo zapisana liczba 09 nie jest poprawnie zbudowanym literałem Javy, gdyż cyfra 9 nie należy do systemu ósemkowego. Dużo większe znaczenie mają w informatyce liczby szesnastkowe (heksadecymalne), gdyż składają się z cyfr odpowiadających kolejnym czwórkom bitów, a jak wiadomo, długość słowa maszynowego wszystkich procesorów jest podzielna przez 4. Ponieważ dziesiętny system liczenia zawiera tylko cyfry od 0 do 9, pozostałych sześć cyfr systemu

14 Wykład Java ver szesnastkowego, od 10 do 15, zapisuje się za pomocą liter od A do F (ich wielkość nie ma znaczenia). Przed każdym literałem szesnastkowym muszą występować znaki Ox lub OX. Jak więc z tego wynika. Literały całkowite Javy są typu int, w związku z czym zajmują 32 bity, a więc umożliwiają zapisywanie liczb należących do przedziału od około -2 do +2 miliardów. Jeżeli jest on niewystarczający, to trzeba utworzyć wartość typu Iong, dopisując na końcu literału literę L lub l, na przykład Ox7FFFFFFFFFFFL. Ponieważ typ Iong zajmuje 64 bity, to można dzięki niemu tworzyć literały o maksymalnej wartości wynoszącej aż około 9 trylionów (9*10 18 ). Literały zmiennoprzecinkowe Literały zmiennoprzecinkowe reprezentują liczby dziesiętne z częścią ułamkową. Można je zapisywać na dwa sposoby: w postaci standardowej i wykładniczej. Zapis standardowy składa się z cyfr oznaczających część całkowitą (początkowe zero można pominąć), kropki dziesiętnej (odpowiednika przecinka dziesiętnego w krajach anglosaskich) i cyfr oznaczających część ułamkową, na przykład 2.0, i Zapis wykładniczy zawiera dodatkowo literę E lub e oraz liczbę oznaczającą wykładnik potęgi (dodatni lub ujemny), do której należy podnieść liczbę 10, na przykład 6.022E23 (= 6,022 * ), E-5 (= *10-5 lub 2e+100 (= 2 * ). Literały Logiczne Istnieją tylko dwa literały logiczne (boolowskie), czyli wartości, jakie mogą przyjmować wyrażenia typu boolean: true i false. Inaczej niż w językach C/C++, nie mają one odpowiedników w postaci wartości całkowitych: true nie jest równe 1, a false to nie 0. Wynika stąd, że zmiennym typu boolean nie wolno przypisywać wartości numerycznych, a jedynie wymienione dwa literały logiczne Literały znakowe W Javie można zapisywać wszystkie znaki należące do zestawu Unicóde. Są one reprezentowane przez liczby 16-bitowe, które można przekształcać do typu int i wykonywać na nich działania za pomocą operatorów całkowitych. Literały znakowe umieszcza się między apostrofami. Wszystkie drukowalne (dające się wyświetlić i wydrukować) znaki ASCI I można zapisywać bezpośrednio, na przykład 'a', 'z' czy Natomiast znaki, które nie mają odpowiadających im klawiszy, zapisuje się w postaci tak zwanych sekwencji escape; na przykład '\" to apostrof, a '\n' znak nowego wiersza. Istnieje również możliwość bezpośredniego określania wartości liczbowej zapisywanego znaku.

15 Wykład Java ver Zapis ósemkowy składa się ze znaku \ i trzech cyfr, na przykład '\141' oznacza literę a. Natomiast użycie liczby szesnastkowej wymaga wpisania znaków \u, a następnie 4 cyfr szesnastkowych. Na przykład '\u0061' oznacza literę a (pierwsze dwa zera charakteryzują zestaw znaków ISO-Latin-1), natomiast '\ua432'-jeden ze znaków alfabetu japońskiego Katakana. Wszystkie sekwencje escape zostały zestawione w Tabela 1. Sekwencje Escape są podobne do stałych znakowych języka C/C++ z ukośnikiem wstecznym. Tabela 1 Sekwencja Escape Sekwencja Escape \ddd Znak ósemkowy (ddd) \uxxxx Znak heksadecymalny UNICODE (xxxx) \' Apostrof \" Cudzysłów \\ Ukośnik tylny (ang. Backslash) \r Znak powrotu karetki, CR (ang. Carriage return) \n Znak nowego wiersza, LF (ang. Line feed) \f Znak nowej strony, FF (ang. Form feead) \t Znak tabulacji poziomej, HT (ang. Horizontal tab) \b Znak cofania, BS (ang. Backspace) Standard kodowania - Unikod (Unicode) Unikod (Unicode) jest sposobem kodowania obejmującym praktycznie wszystkie znaki używane na całym świecie. W skład Unikodu wchodzą również symbole np. techniczne, muzyczne i itp. Ogólem w wersji 3.0 Unikodu jest prawie 50 tyś. znaków. Unikod jednoznacznie identyfikuje symbol. Pozwala to swobodne umieszczać znaki różnych krajów razem, bez obaw o pomyłki. Zestaw polskich znaków UNICODE. Znak heksadecymalny: UNICODE: \u... dziesiętny: ą ć ę ł ń ó F

16 Wykład Java ver ś ź ż Ą Ć Ę Ł Ń Ó Ś Ż Ź 015B 017A 017C D3 015A B Jak używać UNICODE Użycie UNICODE w programach Java jest bardzo proste. Jeżeli chcemy, aby np. tekst w polu typu Label zawierał polski znak, znak ten zamieniamy na odpowiednią wartość UNICODE. Label lb1 = new Label(); lb1.settext("nowo\u015bci"); Znak "ś" w słowie "Nowości" został zamieniony Sposoby kodowania Ze względu na to iż nie wszystkie dostępne systemy i programy zdolne są do wspierania Unikodu w pełnym zakresie oraz dla zapewnienia bezproblemowego transferu danych przy użyciu takich systemów określono kilka sposobów kodowania: UTF-7 - format 7-bitowy UTF-8 - format 8-bitowy UTF-16 - format 16-bitowy występujący w dwóch odmianach różniących się kolejnością ułożenia bajtów w słowie:

17 Wykład Java ver Literały Łańcuchowe Literały łańcuchowe Javy wyglądają tak samo jak we wszystkich innych językach programowania, czyli znajdują się w cudzysłowie. Fakt, że dla każdego z nich jest tworzony oddzielny obiekt, pozostaje dla programisty niewidoczny. Można korzystać ze wszystkich sekwencji escape zdefiniowanych dla pojedynczych znaków. Do przykładów poprawnie zbudowanych literałów łańcuchowych należą między innymi: Witamy wszystkich, "dwa\nwiersze" i "\ "Ten tekst jest w cudzysłowie \ "". Każdy literał musi znajdować się w całości w jednym wierszu; nie istnieje znak kontynuacji wiersza, spotykany w niektórych innych językach programowania. Operatory Operatory są elementami leksykalnymi języków programowania, które pobierają jeden lub więcej argumentów (operandów) i generują określony wynik. Umieszcza się je obok identyfikatorów i literałów, zwykle między nimi. Operatory to specjalne znaki instruujące kompilator, aby wykonał określoną operację na operandach, będących zmiennymi, wyrażeniami lub literałami. W Javie istnieją operatory jedno- i dwuargumentowe oraz jeden trójargumentowy. Niektóre operatory jednoargumentowe umieszcza się przed operandem, a inne za nim; pierwsze z nich nazywa się operatorami przedrostkowymi (ang. prefix), drugie - przyrostkowymi (ang. postfix). Operatory dwu- i trójargumentowe znajdują się zawsze między operandami, dlatego są one określane mianem operatorów wrostkowych (ang. infix). Operatory dwuargumentowe umożliwiają wykonywanie działań znanych powszechnie z arytmetyki, takich jak dodawanie czy mnożenie. W Javie istnieją łącznie 44 operatory. Można je podzielić na cztery następujące grupy: operatory arytmetyczne, bitowe, relacyjne i logiczne. Dla każdego operatora jest określony typ operandów i rodzaj wykonywanej operacji. Nieraz działanie operatora zależy od typu jego operandów. Tabela 2 Operatory Javy Priorytet Operator Priorytet Operator 1. [] () 9 ^ ! ~ instanceof 10 3 * / % 11 && << >> >>> 13?:

18 Wykład Java ver < > <= >= 14 = op= 7 ==!= 15, 8 &

19 Wykład Java ver Tabela 3 Operatory Bitowe Javy. Operator & Działanie Koniunkcja, AND Alternatywa,OR Różnica symetryczna, XOR ^ ~ Uzupełnienie do 1, NOT >> Przesunięcie w prawo << Przesunięcie w lewo >>> Przesunięcie w prawo bez znaku <<< Przesunięcie w lewo bez znaku Operator Działanie - odejmowanie, również minus jednoargumentowy, + dodawanie, * mnożenie, / dzielenie, % dzielenie modulo, oblicz resztę z dzielenia. W przeciwieństwie do C/C++, można go stosować nie tylko z typami całkowitymi, ale także z typami zmiennoprzecinkowymi -- dekrementacja (zmniejszenie o 1), ++ inkrementacja (zwiększanie o 1). Rysunek 1Operatory arytmetyczne Javy.

20 Wykład Java ver Operatory relacyjne Operator Działanie > większy, >= większy lub równy, < mniejszy, <= i mniejszy lub równy, == równy,!= różny, Operatory logiczne Operator Działanie && koniunkcja, AND alternatywa, OR! negacja, NOT?: trójargumentowy operator if then-else Rysunek 2 Operatory relacyjne i logiczne Javy.

21 Wykład Java ver Separatory Poza wymienionymi, istnieje jeszcze tylko kilka innych sekwencji znaków, które mogą występować w poprawnie zbudowanym programie Javy. Są to tak zwane separatory, umożliwiające oddzielenie od siebie poszczególnych elementów leksykalnych języka. Ich postać i przeznaczenie zostały przedstawione w Tabela 4. Tabela 4 Sepatatory Javy. Symbol Nazwa Przeznaczenie () Nawiasy Okrągłe 1. Zapisywanie parametrów w definicjach metod i przekazywanie metodom argumentów. 2. Zmiana kolejności wykonywania działań w wyrażeniach. 3. Zapisywanie wyrażeń w instrukcjach sterujących. 4.Rzutowanie typów. { Nawiasy klamrowe 1. Definiowanie bloków instrukcji, na przykład klas, metod i instrukcji złożonych 2. Zapisywanie wartości automatycznie inicjalizowanych tablic [] Nawiasy kwadratowe Deklarowanie typów tablicowych i odwoływanie się do elementów tablic ; Średnik Część składowa instrukcji, Przecinek l. Oddzielanie identyfikatorów w deklaracji zmiennych tego samego typu. 2.Oddzielanie instrukcji znajdujących się wewnątrz instrukcji for.. Kropka Oddzielanie nazw klas od nazw podklas i metod oraz nazw obiektów od nazw metod i zmiennych egzemplarzowych.

22 Wykład Java ver Zmienne Zmienne można określić jako podstawowe jednostki pamięci wykorzystywanej przez program. Każdą zmienną Javy deklaruje się przez określenie jej nazwy (identyfikatora), typu i dostępu. Ten ostatni atrybut zależy zarówno od położenia deklaracji zmiennej, jak i od użytych modyfikatorów. Istnieją na przykład zmienne dostępne tylko wewnątrz określonej instrukcji złożonej, takiej jak for, zmienne dostępne w pojedynczej metodzie lub klasie, zmienne dostępne w całym programie itp. Deklarowanie zmiennych Ogólna postać deklaracji jednej lub większej liczby zmiennych wygląda następująco: typ identyfikator [=wartość][,identyfikator [=wartość]...]; Za słowo typ można podstawić jeden z ośmiu podstawowych typów danych podanych w Tabela 5 lub nazwę określonej klasy lub interfejsu. Tabela 5 Osiem podstawowych typów danych (typy proste) Typ danych Znaczenie Zakres Rozmiar (w bitach) boolean wartości true/false 8 byte liczba całkowita mała char znak 16 short Liczba całkowita krótka ( int liczba całkowita ( ) 32 long liczba całkowita długa float liczba zmiennoprzecinkowa pojedynczej precyzji 3,4* ,4* void - - double liczba zmiennoprzecinkowa podwójnej precyzji 1,7* ,7* Najczęściej używanymi typami są typy całkowite. Większość programistów zwykle nie zastanawia się nawet, czy ich dopuszczalny zakres jest wystarczający, ponieważ służą one najczęściej do zapisywania niewielkich wartości. Zresztą w większości języków programowania dopuszczalny zakres poszczególnych typów nie jest dokładnie określony. Inaczej wygląda sytuacja w Javie - tutaj szerokość poszczególnych typów (liczba bitów) jest dokładnie określona; na przykład liczby typu int zajmują zawsze 32 bity.

23 Wykład Java ver Bezpieczeństwo i niezawodność programów Javy wynika między innymi ze ścisłej kontroli typów. Kompilator sprawdza, czy wartości przypisywane zmiennym i wyrażeniom są zgodne z ich typami; sprawdzenia takie są dokonywane zarówno w instrukcjach przypisania, jak i w wywołaniach metod. W przeciwieństwie do niektórych innych języków programowania, nigdy nie zachodzi automatyczna konwersja niezgodnych typów. Użycie niewłaściwego typu nie powoduje wygenerowania ostrzeżenia, lecz komunikatu o błędzie, co uniemożliwia skompilowanie danej klasy. Z każdym typem jest związany określony zbiór wartości, które może on reprezentować, oraz zestaw operacji, które można wykonywać na jego zmiennych. Na przykład dozwolone jest dodawanie liczb typu int czy float, ale nie wartości typu boolean. Typy numeryczne służą do zapisywania liczb. Są one potrzebne podczas wykonywania każdego działania arytmetycznego, zarówno do przechowania jego argumentów, jak i wyniku. Istnieją dwa rodzaje typów numerycznych: całkowite i zmiennoprzecinkowe. Pierwsze z nich umożliwiają, zgodnie z nazwą, zapisywanie liczb całkowitych, a drugie rzeczywistych, czyli posiadających część ułamkową. Dla każdego typu numerycznego jest dopuszczalny zakres wartości, a dla typów zmiennoprzecinkowych dodatkowo największa dokładność, czyli maksymalna liczba cyfr po przecinku. To, z którego typu należy skorzystać, zależy od danej aplikacji. W Javie istnieją wszystkie typy numeryczne standardu ANSI C. Jedyna różnica, jaka istnieje między tymi językami, polega na tym, że w Javie wszystkie typy numeryczne mają ściśle określoną szerokość (zakres i dokładność). Natomiast w C liczba bitów przydzielanych poszczególnym typom zależy od danej implementacji kompilatora. Zmienna szerokość typu int, dostosowywana do długości słowa maszynowego, stanowi główną przyczynę braku przenośności programów C. Pod pojęciem słowa maszynowego rozumiemy liczbę bitów rejestrów wewnętrznych procesora, stosowanych do zapamiętywania liczb i wykonywania na nich operacji arytmetycznych. W latach siedemdziesiątych długość słowa maszynowego większości komputerów osobistych wynosiła 8 bitów. Lata osiemdziesiąte przyniosły zaprojektowanie procesorów 16 bitowych rodziny Wraz z pojawieniem się procesorów 486 i Pentium, standardem stały się 32-bitowe słowa maszynowe. Wreszcie, rozpoczęcie produkcji układów Pentium Pro i UItraSPARC rozpoczęło erę komputerów 64-bitowych. Tak więc, w zależności od użytego kompilatora, typ int języka C jest zdefiniowany jako 16, 32 lub 64 bity. Deklarując zmienną typu int, programista C zdaje się mówić kompilatorowi: przydziel mi liczbę bitów odpowiadającą długości słowa

24 Wykład Java ver maszynowego. Rozwiązanie to ma tę zaletę, że gwarantuje największą efektywność programów. Zupełnie inaczej funkcjonuje Java - tutaj typ int zajmuje zawsze 32 bity, niezależnie od tego, na jakim komputerze są uruchamiane programy. Oczywiście prawdą jest, że aplikacja napisana dla komputera 64-bitowego działałaby szybciej, gdyby kompilator przydzielał zmiennym typu int po 64 bity. Wówczas jednak stracilibyśmy jej niezależność od sprzętu, gdyż w inny sposób mogłaby ona działać na komputerach 32-bitowych, a w inny na komputerach 64-bitowych. Na przykład mogłoby się okazać, że zbyt mała liczba bitów spowodowałaby wystąpienie nadmiaru lub niedomiaru. Ściśle określona szerokość typów jest więc jedną z tych właściwości Javy, gdzie niezależność od sprzętu zwyciężyła nad efektywnością. Zmienne globalne W czasach panowania FORTRAN-u, kiedy "prawdziwi mężczyźni" programowali w asemblerach, a tekst programów zapisywano na kartach perforowanych, zmienne globalne były na porządku dziennym. Dlatego możliwość stosowania ich przewidziano także w języku C, choć wprowadzono dodatkowe ograniczenie, polegające na konieczności deklarowania ich typu. Problem towarzyszący używaniu zmiennych globalnych polega oczywiście na tym, że można do nich uzyskać dostęp z każdego miejsca programu. W ten sposób powstaje wiele błędów, czasami o katastrofalnych skutkach, polegających na przykład na przypadkowej zmianie stanu programu. Istnienie zmiennych globalnych w programie C++ świadczy o tym, że nie wykorzystano w nim w pełni możliwości programowania zorientowanego obiektowo, a dokładniej - że nie dokonano w wystarczającym stopniu enkapsulacji danych. W Javie jedynymi nazwami globalnymi są nazwy klas. Zdefiniowanie zmiennej poza klasą jest po prostu niemożliwe. Co prawda, istnieje możliwość deklarowania statycznych zmiennych publicznych, które w praktyce zachowują się tak samo, jak zmienne globalne, ale używanie ich nie jest zalecane. Zresztą, nawet, jeśli zmienne takie istnieją, to są one zawsze przydzielone do określonej klasy. Typy całkowite Ponieważ programiści C/C++ używają często zmiennych całkowitych do zapisywania masek bitowych, wartości kolorów i innych liczb przyjmujących wyłącznie wartości dodatnie, wprowadzono modyfikator typu unsigned.. W Javie modyfikator taki nie istnieje, a wszystkie zmienne całkowite mogą przyjmować zarówno wartości dodatnie, jak i ujemne. O znaku liczby decyduje zawsze pierwszy bit z lewej strony (dla liczb dodatnich jest równy ), a dla ujemnych 1). Tak więc )x80 to w Javie -1.

25 Wykład Java ver Typ byte Typ byte zajmuje 8 bitów, umożliwia więc zapisywanie liczb z zakresu od -128 do 127. Najbardziej nadaje się do wczytywania danych z plików lub sieci, gdyż umożliwia rozpoznawanie protokołów sieciowych i formatów plików. Oprócz tego używa się go do wykonywania operacji bitowych. Poza tymi przypadkami, a więc na przykład podczas wykonywania typowych obliczeń, należy unikać stosowania typu byte, a zamiast niego korzystać z omówionego niżej typu int. Podane niżej dwie instrukcje przykładowe deklarują zmienne b i c typu byte oraz przypisują drugiej z nich wartość szesnastkową 0x55. byte b; byte c = 0x55; Typ short Typ short jmuje 16 bitów, w związku z czym umożliwiają zapisywanie liczb z zakresu od do Jest najrzadziej używanym typem Javy, ponieważ charakteryzuje się zapisywaniem bajtów w innej kolejności, niż na komputerach z procesami Intela (najpierw bardziej znaczącego bajtu, a potem mniej znaczącego). Oto dwa przykłady deklaracji zmiennych typu short: short s; short t=0x55aa; Istnieją dwa sposoby zapisywania w pamięci liczb zajmujących więcej niż jeden bajt, czyli takich, jak short, int czy long. Różnią się one kolejnością zapisywania bajtów tworzących daną liczbę. Jeden z nich, stosowany między innymi w komputerach SPARC i PowerPC, polega na tym, że jako pierwszy zapisywany jest najbardziej znaczący bajt, a jako ostatni najmniej znaczący. Inne rozwiązanie przyjęto w komputerach z procesorem Intela; charakteryzuje się ono tym, że bajty zapisywane są w kolejności od najmniej do najbardziej znaczącego. Istnieją dwa sposoby zapisywania w pamięci liczb zajmujących więcej niż jeden bajt, czyli takich, jak short, int czy long. Różnią się one kolejnością zapisywania bajtów tworzących daną liczbę. Jeden z nich, stosowany między innymi w komputerach SPARC i PowerPC, polega na tym, że jako pierwszy zapisywany jest najbardziej znaczący bajt, a jako ostatni najmniej znaczący. Typ int

26 Wykład Java ver Typ int zajmuje 32 bity, w związku z czym umożliwia zapisywanie liczb należących do zakresu od do Jest najczęściej używanym typem całkowitym. Ponieważ pozwala zapisywać bardzo duże liczby, aż do ponad 2 miliardów, to nadaje się świetnie do stosowania w pętlach i indeksowania tablic. Jego dodatkową zaletę stanowi fakt, że zapewnia on efektywne działanie programów na używanych dzisiaj najczęściej komputerach 32-bitowych oraz tych komputerach 64-bitowych, które mogą działać w szybkim trybie 32-bitowym. Każde wyrażenie, w którym występują zmienne i literały typu byte, short i int, jest automatycznie przekształcane do typu int przed rozpoczęciem wykonywania obliczeń. int i; int j = 0x55aa0000; Typ int jest najbardziej wszechstronny i efektywny ze wszystkich typów całkowitych, dlatego należy go zawsze stosować podczas wykonywania operacji arytmetycznych i indeksowania tablic. Wydawać by się mogło, że używając typu byte lub short można zaoszczędzić pamięć, ale i tak nie ma gwarancji, że Java nie przekształci ich automatycznie do typu int. W zasadzie typ określony w deklaracji zmiennej decyduje jedynie o jej zachowaniu się, a nie o liczbie bajtów, jakie będzie zajmować w pamięci. Jedynym wyjątkiem od tej reguły są tablice, których elementom jest zawsze przydzielana liczba bajtów odpowiadająca podanemu w tekście źródłowym typowi. Typ long zajmuje 64 bity, umożliwia więc zapisywanie tak olbrzymich liczb, że ich podawanie nie ma nawet sensu. Przypadki, kiedy typ int okazuje się niewystarczający i zachodzi potrzeba użycia typu long, są bardzo rzadkie. Należy do nich na przykład zliczanie milisekund w okresie roku lub dłuższym czy mnożenie bardzo dużych liczb. Oto dwa przykłady deklaracji zmiennych typu long: long m; long n=0x55aa000055bb0101; Jak już wspomniałem wcześniej, rodzaj typu całkowitego nie należy rozumieć jako liczbę przydzielanych mu bajtów pamięci, lecz jako sposób wykonywania działań na jego zmiennych i wyrażeniach. Kompilator Javy ma prawo przydzielać poszczególnym typom dowolną liczbę bajtów, dążąc do zapewnienia możliwie jak największej efektywności programów. Na przykład jego aktualna wersja implementuje typu bajt i short jako słowa 32- bitowe, gdyż taka jest właśnie długość słów maszynowych zdecydowanej większości używanych obecnie komputerów. Oczywiście nie oznacza to, że wszystkie 32 bity są wykorzystywane.

27 Wykład Java ver Przypisując zmiennej wartość przekraczającą dopuszczalny zakres jej typu, powoduje się obcięcie nadmiernej liczby bitów, czyli wykonanie odpowiedniej operacji modulo (operacji dającej w wyniku resztę z dzielenia). Na przykład, jeżeli zmienna x jest typu byte, to instrukcja x = 257 powoduje zapisanie w niej liczby 1. (gdyż = ). Zakresy poszczególnych typów całkowitych różnią się w znacznie większym stopniu, niż wynikałoby to z porównania ich szerokości. Aby to sobie lepiej wyobrazić, załóżmy, że liczymy mijające sekundy. Typ byte umożliwia zapisanie kilku minut, short całego dnia, int przeciętnej długości życia człowieka, a long- więcej niż istnienie wszechświata! Typy zmiennoprzecinkowe Liczb zmiennoprzecinkowych, zwanych w matematyce oraz w niektórych językach programowania liczbami rzeczywistymi, używa się na przykład podczas obliczania pierwiastka kwadratowego liczby lub wykonywania funkcji trygonometrycznych, takich jak sinus czy cosinus. W Javie jest zaimplementowany zestaw typów i operatorów zmiennoprzecinkowych zgodny ze standardem IEEE-754. Istnieją dwa typy zmiennoprzecinkowe: float i double; ich szerokość i typ zostały podane w Tabela 5. Rzutowanie typów Rzutowanie typów z C zostało przeniesione do Javy. Zdarzają się bowiem sytuacje, w których wartość określonego typu trzeba zapisać w zmiennej innego typu. Jeżeli zakres i dokładność zmiennej docelowej są na tyle duże, że można w niej zapisać wartość źródłową bez utraty informacji, to kompilator dokonuje automatycznej konwersji typów. Dzieje się tak na przykład' podczas zapisywania wartości typu byte w zmiennej typu int. Tego typu konwersja nazywa się poszerzaniem (ang. widening lub promotion) typów, gdyż węższy typ jest przekształcany w szerszy. W przypadku przeciwnym, czyli podczas zapisywania wartości typu szerszego w zmiennej typu węższego konieczne jest jawne rzutowanie typu. Na przykład, aby zapi- sać liczbę typu int w zmiennej typu byte, trzeba rzutować typ int do typu byte. Operację taką nazywa się nieraz zawężaniem (ang. narrowing) typów, gdyż polega ona na świadomym zmniejszaniu liczby bitów danej wartości, aby zmieścić ją w zmiennej węższego typu. Typ docelowy rzutowania umieszcza się w nawiasach przed wartością źródłową, na przykład (byte) value. Podane niżej instrukcje pokazują rzutowanie typu int do typu byte

28 Wykład Java ver int a = 100: byte b = (byte) a: Automatyczna konwersja typów w wyrażeniach Typy wyników częściowych obliczeń muszą często zapewniać większy zakres i dokładność niż typ wyniku końcowego. Przyjrzyjmy się na przykład podanemu niżej przykładowi, w którym wszystkie argumenty są deklarowane jako zmienne typu byte: byte a = 40; byte b = 50; byte c = 100; int d = a * b / c; Ponieważ jest bardzo prawdopodobne, że wynik mnożenia a * b przekroczy dopuszczalny zakres typu byte, kompilator Javy automatycznie przekształca go do typu wyniku (zmiennej d), czyli do typu int. Konwersja taka przydaje się między innymi w podanym przykładzie, w którym a * b = 2000, gdy tymczasem typ byte pozwala jedynie na zapisywanie liczb z zakresu od -128 do 127. Czasem jednak automatyczna konwersja typów powoduje niespodziewane błędy. Dzieje się tak wtedy, gdy w wyrażeniach występują nie tylko zmienne, ale także literały. Przypomnijmy, że wszystkie literały całkowite, za którymi nie występuje litera L, są traktowane jako liczby typu int, a literały zmiennoprzecinkowe bez końcowej litery F - jako liczby typu double; litera L oznacza typ long, a F - float. Zwróćmy na przykład uwagę na pozornie poprawne, następujące instrukcje: byte b = 50; b = b * 2; ^ Incompatible type for =.. Explicit cast needed to convert int to byte. Błąd zasygnalizowany przez kompilator wynika z faktu, że liczba 2 jest traktowana jako wartość typu int, w związku z czym do tego typu jest również przekształcane wyrażenie b * 2. Powoduje to próbę zapisania wartości typu int w zmiennej typu byte, czego nie wolno wykonywać bez jawnej konwersji ze względu na możliwość utraty informacji. Co prawda, w tym przypadku wynik mnożenia, 100, jest mniejszy od maksymalnej wartości typu bajt, ale oczywiście nie można tego traktować jako reguły. Dlatego podane instrukcje należy zapisać w następujący sposób: byte b = 50; b = (byte) (b * 2) ;

29 Wykład Java ver Typ każdego wyrażenia jest zawsze automatycznie przekształcany do najszerszego typu występujących w nim zmiennych i literałów. Na przykład, jeśli w wyrażeniu występują zmienne typu byte, short i int, to całe wyrażenie uzyskuje typ int; jeśli obecna jest przynajmniej jedna zmienna typu long, to i całe wyrażenie jest tego typu. W przypadku, gdy wyrażenie zawiera wartości całkowite i zmiennoprzecinkowe, typem wynikowym jest typ szerszy zmiennoprzecinkowy. Oznacza to na przykład, że wynik operacji wykonanej na zmiennych typu int i float jest typu float. Podana niżej definicja klasy jest przykładem wielokrotnej automatycznej konwersji typów: class poszerzanie {public static void main(string args[]) { byte b=42; char c='a'; short s=1024; int i=50000; float f=5.67f; double d=.1234; double wynik =(f*b)+(i/c)-(d*s); System.out.println((f*b)+"+"+(i/c)+"-"+(d*s)); System.out.println("Wynik="+wynik); b=(byte)(b*2); System.out.println(b/2+"*2="+b); Zakres zmiennych Instrukcje złożone, czyli sekwencje instrukcji prostych, rozpoczynają się i kończą nawiasami klamrowymi. Każda zmienna jest widoczna (dostępna) od miejsca jej deklaracji do końca zawierającej ją instrukcji złożonej. Instrukcje złożone mogą być zagnieżdżone, czyli w jednej instrukcji złożonej może występować inna, i każda z nich może zawierać własne zmienne lokalne; niedozwolone jest jednak stosowanie w odniesieniu do nich takich samych identyfikatorów. Podana niżej definicja klasy jest nieprawidłowa, gdyż występują w niej deklaracje dwóch zmiennych o takiej samej nazwie. Instrukcje takie można by natomiast umieścić w programie C lub C++, ponieważ obie zmienne bar mają różne zakresy. class zakres {public static void main(string args[]) {int bar=1;

30 Wykład Java ver {int bar=2; //Utworzenie nowego zakresu //bład komplacji Tablice Na pierwszy rzut oka wydaje się, że tablice Javy funkcjonują w taki sam sposób jak tablice C++. Należy jednak być ostrożnym, gdyż między tablicami występującymi w obu tych językach istnieją mało zauważalne, choć ważne różnice. Tablice jednowymiarowe Aby utworzyć tablicę, należy najpierw utworzyć zmienną tablicową odpowiedniego typu. Ogólna postać deklaracji jednowymiarowej tablicy wygląda następująco: typ nazwa zmiennej[]; Słowo typ oznacza tu typ bazowy tablicy. Zauważmy, że między nawiasami kwadratowymi nie ma wymiaru; jest to spowodowane tym, że podaje się go w późniejszej instrukcji. Typ bazowy tablicy określa typ każdego jej elementu, czyli - innymi słowy - typ danych, które będą w tej tablicy zapisywane. Na przykład podana niżej instrukcja deklaruje tablicę liczb całkowitych (typu bazowego int), o nazwie numbers: int numbers[]; Mimo iż deklaracja ta tworzy zmienną tablicową numbers, to jednak po jej wykonaniu nie istnieje jeszcze żadna tablica. Zmiennej numbers jest bowiem przypisywana wartość początkowa null, reprezentująca tablicę nie zawierającą żadnego elementu. Aby powiązać zmienną numbers z rzeczywistą tablicą liczb całkowitych, należy przydzielić jej pamięć za pomocą operatora new. Ogólna postać operatora new zastosowanego do tablicy jednowymiarowej wygląda następująco: zmienna tablicowa = new typ[rozmiar]; Tutaj słowa typ i rozmiar określają typ i liczbę elementów tablicy, a zmienna_tablicowa jest zmienną tablicową, która ma zostać powiązana z tworzoną tablicą. Jak więc widać, użycie operatora new w celu utworzenia tablicy wymaga podania typu i liczby jej elementów. Wszystkie elementy tablicy tworzonej za pomocą operatora new uzyskują wartości początkowe równe zeru. Podana niżej instrukcja tworzy tablicę liczb całkowitych i wiąże ją ze zmienną numbers: numbers = new int[100];

31 Wykład Java ver Po wykonaniu tej instrukcji zmienna numbers będzie odwoływać się do tablicy 100 elementów całkowitych, przy czym na początku będą one wszystkie równe zeru. Streśćmy podane wyżej informacje. Tworzenie tablicy jest procesem dwuetapowym: najpierw trzeba zadeklarować zmienną odpowiedniego typu tablicowego, a następnie przydzielić tablicy pamięć za pomocą operatora new i przypisać ją zadeklarowanej wcześniej zmiennej. Tak więc, w Javie wszystkie tablice - podobnie jak obiekty - są tworzone dynamicznie. Po utworzeniu tablicy można z niej korzystać tak samo, jak z tablic C++. Do elementów wspólnych obu języków należy między innymi fakt, że indeksy tablicy rozpoczynają się od zera i że w celu uzyskania dostępu do określonego elementu tablicy należy umieścić jego indeks w nawiasach kwadratowych. Na przykład pierwsza z podanych niżej instrukcji przypisuje wartość 28 drugiemu elementowi tablicy numbers, a druga wyświetla wartość czwartego elementu: numbers[1]=28; System.out.println(numbers[3]); Poniższy przykład pokazuje sposób tworzenia tablic jednowymiarowych class tablica {public static void main(string args[]) { int numbers[]; numbers=new int[100]; int i; for(i=0;i<100;i++) numbers[i]=i*i; for(i=0;i<100;i++) System.out.println("Kwadrat liczby "+i+" wynosi:"+numbers[i]); druga wersja tego programu class tablica1 { public static void main(string args[]) { int numbers[]=new int[100]; // istnieje możliwość połączenia deklaracji zmiennej tablicowej z przydzielaniem pamięci //samej tablicy int i;

32 Wykład Java ver for(i=0;i<100;i++) numbers[i]=i*i; for(i=0;i<100;i++) System.out.println("Kwadrat liczby "+i+" wynosi:"+numbers[i]); Deklarowane tablice można jednocześnie inicjalizować, przy czym proces ten przebiega niemal tak samo, jak w C++. Kompilator Javy tworzy na tyle dużą tablicę, aby można w niej było pomieścić wszystkie wyszczególnione wartości. W tym przypadku nie ma potrzeby stosowania operatora new. Na przykład podany niżej program inicjalizuje tablicę 10 liczb całkowitych: class tablica2 {public static void main(string args[]) { int numbers[]={0,1,2,3,4,5,6,7,8,9; //przy takiej deklaracji tablicy operator new jest zbędny int i; for(i=0;i<10;i++) System.out.println("Kwadrat liczby "+i+" wynosi:"+numbers[i]); Java nie dopuszcza do przekroczenia granic tablic. Mówiąc inaczej, podczas wykonywania programu sprawdzana jest poprawność operacji wykonywanych na tablicach w celu wykrycia ewentualnych błędów polegających na zastosowaniu nieodpowiednich wartości indeksów (pod tym względem Java zdecydowanie różni się od języków C/C++, które charakteryzują się brakiem wykrywania błędów przekroczenia zakresu tablicy). Na przykład w podanym wyżej programie nie jest możliwe uzyskanie dostępu do elementu tablicy numbers o indeksie nie należącym do zakresu od 0 do 9. Próba wykonania takiego działania spowodowałaby zasygnalizowanie błędu.

33 Wykład Java ver Tablice wielowymiarowe W Javie wielowymiarowe tablice są właściwie tablicami tablic. Mimo iż wykazują one duże podobieństwo do tablic C++, to jednak pod pewnymi względami różnią się od nich. Aby zadeklarować zmienną oznaczającą tablicę wielowymiarową, należy określić każdy indeks przez podanie osobnej pary nawiasów kwadratowych. Na przykład podana niżej instrukcja deklaruje dwuwymiarową tablicę o nazwie tablica2d: int tablica2d[][]=new int[4][5]; Instrukcja ta przydziela pamięć tablicy o wymiarach 4x5 i przyporządkowuje ją zmiennej tablica2d. Wewnętrznie tablica ta jest realizowana jako tablica tablic liczb całkowitych. Podczas przydzielania pamięci tablicy wielowymiarowej wystarczy podać tylko pierwszy (położony najbardziej na lewo) wymiar. Pozostałe wymiary można określić później. Na przykład pierwsza z podanych niżej instrukcji przydziela pamięć jedynie pierwszemu wymiarowi tablicy tablica2d, natomiast pamięć dla pozostałych wymiarów jest przydzielana osobno: int tablica2d[][]=new int[4][]; tablica2d[0]=new int[1]; tablica2d[1]=new int[2]; tablica2d[2]=new int[3]; tablica2d[3]=new int[4]; W tej sytuacji indywidualne przydzielanie pamięci tablicom drugiego wymiaru nie przynosi żadnych korzyści, ale w innych sytuacjach działanie takie może być pożądane. Na przykład "ręczny" przydział pamięci poszczególnym tablicom pozwala określić różną liczbę elementów tablic tego samego wymiaru. To, że długość każdej tablicy może zostać ustalona

34 Wykład Java ver oddzielnie, wynika z faktu, iż -jak wiadomo - tablice wielowymiarowe Javy są w rzeczywistości tablicami tablic: Podany niżej program tworzy dwuwymiarową tablicę, dla której wartości drugiego wymiaru są różne: class tablica2dw {public static void main(string args[]) { int tablica2d[][]=new int[4][]; tablica2d[0]=new int[1]; tablica2d[1]=new int[2]; tablica2d[2]=new int[3]; tablica2d[3]=new int[4]; int i,j,k; for(i=0,k=0;i<4;i++) for(j=0;j<i+1;j++) tablica2d[i][j]=k++; for(i=0;i<4;i++){ for(j=0;j<i+1;j++) System.out.print(tablica2d[i][j]+" "); System.out.println(); Program ten wyświetla następujące dane: Czyszczenie pamięci Ponieważ tablice i obiekty są tworzone dynamicznie za pomocą operatora new, pojawia się pytanie: w jaki sposób elementy te są niszczone w celu zwolnienia zajmowanej przez nie pamięci? W niektórych językach, na przykład w C++, pamięć przydzielona obiektom dynamicznie musi być zwolniona ręcznie (w C++ za pomocą operatora delete). W Javie zastosowano inne rozwiązanie: w języku tym operacje związane ze zwalnianiem pamięci są wykonywane automatycznie, z wykorzystaniem techniki zwanej czyszczeniem pamięci lub zbieraniem odpadków (ang. garbage collection). Opiera się ona na założeniu, że jeżeli nie istnieje odwołanie do danego obiektu, to obiekt ten nie jest już potrzebny i można zwolnić przydzieloną mu pamięć.

35 Wykład Java ver W programach Javy nie trzeba więc niszczyć obiektów w taki sposób, jak w C++. Trzeba jednak pamiętać o tym, że podczas działania programu czyszczenie pamięci odbywa się sporadycznie - może się nawet zdarzyć, że ani razu. Fakt, że jeden lub więcej obiektów nie jest już wykorzystywanych, nie wystarcza do tego, by pamięć została natychmiast wyczyszczona. Zresztą, poszczególne systemy czasu przebiegu Javy stosują różne podejście do czyszczenia pamięci. Pomimo tych zastrzeżeń w większości przypadków programista Javy nie musi (i nie powinien) zajmować się niszczeniem tworzonych dynamicznie obiektów. Metoda finalize() Niektóre obiekty muszą wykonać przed zniszczeniem określone działania. Na przykład, jeżeli obiekt korzysta z zasobu nie należącego do Javy, takiego jak plik czy czcionka (font), to może być konieczne zwolnienie tego zasobu przed zniszczeniem samego obiektu. Aby umożliwić odpowiednie napisanie programu w tego typu sytuacjach, projektanci Javy wprowadzili mechanizm zwany finalizacją (ang. finalization). Pozwala on określić działania, które mają być wykonane tuż przed zniszczeniem go przez program odzyskujący odpadki (program czyszczący pamięć, ang. garbage collector). Aby skorzystać z mechanizmu finalizacji, należy zdefiniować w odpowiedniej klasie metodę finalize(). System czasu przebiegu Javy wywołuję tę metodę przed zwolnieniem pamięci przydzielonej dowolnemu obiektowi jej klasy. W metodzie finalize() należy więc umieścić instrukcje, które powinny być wykonane przed zniszczeniem obiektu. Ogólna postać metody finalize() wygląda następująco: protected void finalize() { // istukcje finalizacji Należy koniecznie pamiętać o tym, że metoda finalize() jest wywoływana tylko przed czyszczeniem pamięci. Nie jest natomiast wywoływana wtedy, gdy obiekt przestaje być dostępny dla aktualnie wykonywanego fragmentu programu. Wynika stąd, że nie można określić chwili, w której metoda ta zostanie wywołana; może się nawet zdarzyć, że nie nastąpi to ani razu. Dlatego zasoby wykorzystywane przez obiekt powinny być zwalniane przez program w inny sposób. Normalnego funkcjonowania programu nie można opierać na działaniu metody finalize().

36 Wykład Java ver if (wyrażenie) { sekwencja instrukcji1; else { sekwencja instrukcji2; if (wyrażenie) instrukcja1; else instrukcja2; wyrażenie Fałsz Prawda sekw. instrukcji 1 Stopniowanie if-else-if if (wyrażenie1) instrukcja1; else if (wyrażenie2) instrukcja2; else if (wyrażenie3) instrukcja3;... else instrukcja4; sekw. instrukcji 2 Stop Stop switch (wyrażenie){ case stała1: sekw. instrukcji1; braeak; case stała2: sekw. instrukcji2; braeak; case stała3: sekw. instrukcji3; braeak; default: sekw.instrukcji4; Prawda stała1 Fałsz Prawda stała2 Fałsz sekw. instrukcji 1 sekw. instrukcji 2 sekw. instrukcji 4 stała3 Fałsz Prawda sekw. instrukcji 3 Instrukcja Break Język Java nie zawiera instrukcji goto, która w innych językach programowania pozwala na wykonanie skoku (przejście) do dowolnego miejsca programu. Stosowanie jej zmniejsza czytelność tekstu źródłowego i uniemożliwia wykonanie pełnej optymalizacji kodu wynikowego przez kompilator. Istnieją jednak takie sytuacje, w których użycie instrukcji sterującej goto lub jej odpowiednika jest uzasadnione, a nawet potrzebne. W Javie we wszystkich tych przypadkach stosuje się instrukcję break. Nakazuje ona kompilatorowi przejście do pierwszej instrukcji znajdującej się za instrukcją złożoną o podanej nazwie. Nazwy instrukcji definiuje się za pomocą etykiet (ang. labels). Etykieta musi być poprawnie zbudowanym identyfikatorem i znajdować się przed daną instrukcją. Bezpośrednio za definiowaną etykietą umieszcza się dwukropek; znaku tego nie podaje się jednak podczas odwoływania się do etykiety w instrukcji break.

37 Wykład Java ver class break1{public static void main(string args[]) { int i=1; int k=10; Etykieta: { while(i++<100) { if (k--==0) break Etykieta; System.out.println("i="+i+";k="+k+": i*k="+i*k); // wyświetlenie na ekranie wyniku mnożenia //Tu zostałoby przekazane sterowanie gdyby instrukcja //break nie miała etykiety Etykieta. System.out.println(" Koniec"); //koniec bloku instrukcji //Tu zostaje przekazane sterowanie programem po wykonaniu //instrukcji break Etykieta java break1 Wynik zadziałania programu: i=2;k=9: i*k=18 i=3;k=8: i*k=24 i=4;k=7: i*k=28 i=5;k=6: i*k=30 i=6;k=5: i*k=30 i=7;k=4: i*k=28 i=8;k=3: i*k=24 i=9;k=2: i*k=18 i=10;k=1: i*k=10 i=11;k=0: i*k=0 Instrukcja for for (inicjalizacja ; warunek ; inkrementacja) { sekwencja instrukcji1; for (inicjalizacja ; warunek ; inkrementacja) instrukcja1; for (x=0, y=0 ; x+y <10; ++x) { sekwencja instrukcji1; Fałsz inicjalizacja Stop warunek Prawda for (x=0, y=0 ; x+y <10; ++x) ; /* pętla pusta */ sek. instrukcji 1 inkrementacja

38 Wykład Java ver Instrukcja while i do-while do { sekwencja instrukcji1; while (warunek) sek. instrukcji 1 Fałsz warunek Prawda while (warunek) { sekwencja instrukcji 1 ; Fałsz warunek sek. instrukcji 1 Prawda Instrukcja return Instrukcja return umożliwia natychmiastowe zakończenie wykonywania bieżącej metody i powrót do procesu, który ją wywołał. Instrukcja continue Czasami zdarza się, że w danej iteracji trzeba pominąć wszystkie pozostałe instrukcje pętli, ale nadal w niej pozostać. Wykonanie tego działania umożliwia instrukcja continue. Jeżeli występuje ona w pętli while lub do-while, to powoduje przejście do instrukcji sprawdzającej warunek, natomiast jeśli jest obecna w instrukcji for, to przekazuje sterowanie do bloku inkrementacji ( wyrażenia po drugim średniku ). Podobnie jak w przypadku instrukcji break, tak i w continue można podać etykietę określającą pętlę, której wykonywanie ma być kontynuowane. Z właściwości tej korzysta podany niżej program, który wyświetla tabliczkę mnożenia w zakresie od 0 do 9. class continue1 {public static void main(string args[]) { dalej:for(int i=0;i<10;i++) for(int j=0;j<10;j++)

39 Wykład Java ver {if (j>i) {System.out.println(""); continue dalej; System.out.print(" "+(i*j)); Instrukcja continue powoduje tu zakończenie wykonywania pętli z licznikiem j i rozpoczęcie następnej iteracji pętli z licznikiem i, czyli przejście do instrukcji i++. Informacje wyświetlane przez ten program są następujące: Wynik zadziałania programu: Klasy Między C a Javą istnieje wiele podobieństw dotyczących klas; niemniej jednak występują także pewne różnice. Rozpoczynamy od wspólnych elementów klas definiowanych w programach C++ i Javy. Klasy Javy mogą zawierać zarówno zmienne składowe, jak i funkcje składowe, zwane metodami. Dostęp do poszczególnych elementów obiektów klas uzyskuje się za pomocą operatora w postaci kropki. Klasy Javy mogą zawierać konstruktory, które można przeładowywać. Dozwolone jest zresztą przeładowywanie wszystkich metod klas (przeładowywanie funkcjonuje w Javie mniej więcej tak samo jak w C++). Klasa Javy to szablon umożliwiający tworzenie obiektów i deklarowany za pomocą słowa kluczowego class. klasa stanowi narzędzie do tworzenia nowych typów danych, których elementy noszą nazwę obiektów (dla których definicja klasy stanowi wzorzec) i mogą być przypisywane zmiennym obiektowym. Definicja klasy przyjmuje następującą formę: [modyfikatory] class NazwaKlasy [extends NazwaNadklasy] [implements NazwyInterfejsów]

40 Wykład Java ver { // Ciało klasy: specyfikator dostępu typ zmienna_egzemplarzowal ; specyfikator dostępu typ zmienna_egzemplarzowa2 ; //... specyfikator dostępu typ zmienna_egzemplarzowan ; specyfikator dostępu typ nazwa_metody1(lista_parametrów){ //część główna metdoy specyfikator dostępu typ nazwa_metody2(lista_parametrów){ //część główna metdoy Elementy deklaracji pomiędzy nawiasami [ i ] są opcjonalne. Deklaracja klasy definiuje następujące jej właściwości: modyfikatory deklarują rodzaj klasy (np.: public, abstract lub final static); NazwaKlasy określa nazwę deklarowanej klasy(poprawnie zbudowany identyfikator); NazwaNadklasy jest nazwą nadklasy ("prefiksu") deklarowanej przez nas klasy; NazwyInterfejsów jest to lista, rozdzielona przecinkami, nazw interfejsów implementowanych przez naszą klasę. Dane (zmienne) zdefiniowane w klasie nazywają się zmiennymi egzemplarzowymi (ang. instance variabdes), a funkcje -jak wiemy - metodami (ang. methods). Każdy element składowy klasy można poprzedzić specyfikatorem dostępu (ang. access specifier), określającym jego zakres. Dostęp do elementu klasy, który został zmodyfikowany za pomocą słowa public, może uzyskać dostęp każda instrukcja programu. Natomiast elementy zadeklarowane jako private są dostępne jedynie dla pozostałych elementów tej samej klasy. Właśnie dlatego metoda main() musi być zawsze poprzedzona specyfikatorem public (jest ona wywoływana spoza programu - przez system czasu przebiegu Javy). Elementy klas, których dostęp nie został określony jawnie, są traktowane domyślnie jako elementy publiczne w obrębie tego samego pakietu, ale nie mogą do nich uzyskać dostępu instrukcje znajdujące się poza tym pakietem. Specyfikator dostępu musi znajdować się przed pozostałą częścią specyfikacji typu elementu składowego klasy, czyli musi występować na początku instrukcji deklaracji, tak jak w podanych niżej dwóch przykładach:

41 Wykład Java ver public int i; private double j; private int mymethod(int a, char b) { //... Mimo iż klasy Javy są bardzo podobne do klas C++, to nie sposób nie wspomnieć o trzech ważnych, dzielących je różnicach. Są one następujące: 1. W C++ można pisać funkcje nie należące do klas; w Javie nie ma takiej możliwości. 2. Każda metoda Javy musi być zdefiniowana w obrębie swojej klasy; niedozwolone jest zdefiniowanie metody na zewnątrz definicji klasy. 3. Specyfikator dostępu dotyczy tylko tego elementu klasy, przed którym występuje. Inaczej jest w C++, gdzie specyfikatory dostępu są traktowane jako nagłówki, odnoszące się do wszystkich leżących niżej deklaracji, aż do wystąpienia następnego specyfikatora w ramach ciała klasy. 4. Nazwa każdego pliku źródłowego Javy musi być taka sama, jak nazwa zdefiniowanej w nim klasy. Tak więc podaną wyżej definicję klasy Punkt trzeba umieścić w pliku Punkt.java. Zarówno w tekście źródłowym, jak i w nazwach plików rozróżniane są duże i małe litery. Definiowanie metod Metody, czyli podprogramy związane z poszczególnymi klasami, tworzą ich interfejsy. Implementacje wszystkich metod danej klasy muszą znajdować się w obrębie jej definicji, na tym samym poziomie co zmienne egzemplarzowe. Metody mogą korzystać ze zmiennych egzemplarzowych swojej klasy w taki sposób, jakby były one ich zmiennymi lokalnymi. Deklaracja metody musi określać typ zwracanej przez nią wartości, a ponadto może zawierać listę parametrów formalnych. Jej ogólna postać wygląda następująco: typ nazwa_metody(lista parametrów_formalnych) { //

42 Wykład Java ver Nie istnieją ograniczenia dotyczące typów powrotnych metod; jeżeli dana metoda nie zwraca żadnej wartości, to jej typ określa się słowem kluczowym void. Nazwa metody może być dowolnym, poprawnie zbudowanym identyfikatorem, z tym zastrzeżeniem, że żadne dwie metody lub zmienne egzemplarzowe należące do wspólnej klasy nie mogą mieć takich samych nazw. Lista parametrów formalnych składa się z oddzielonych przecinkami par identyfikatorów, z których pierwszy jest nazwą typu, a drugi nazwą parametru. Jeżeli dana metoda nie pobiera żadnych parametrów, to za jej nazwą umieszcza się w deklaracji same nawiasy. Zgodnie ze standardem ANSI C funkcje, które nie pobierają żadnych parametrów, deklaruje się przy użyci słowa void. W Javie taki zapis jest niepoprawny. Warto wspomnieć, że żadna inna metoda nie może mieć takiej samej nazwy co jej klasa. Deklaracje konstruktorów wyglądają trochę dziwnie, ponieważ nie określają typu powrotnego. Jest to spowodowane tym, że typem każdego konstruktora jest typ jego klasy. Poza tym definicje konstruktorów niczym nie różnią się od definicji wszystkich pozostałych metod. Dobrze napisany konstruktor powinien w taki sposób zainicjalizować zmienne egzemplarzowe swojej klasy, aby bez wykonywania dodatkowych działań można było od razu przystąpić do korzystania z jej metod. Przeładowywanie metod Deklaracje konstruktorów nie określają typu powrotnego. Jest to spowodowane tym, że typem każdego konstruktora jest typ jego klasy. Poza tym definicje konstruktorów niczym nie różnią się od definicji wszystkich pozostałych metod. Dobrze napisany konstruktor powinien w taki sposób zainicjalizować zmienne egzemplarzowe swojej klasy, aby bez wykonywania dodatkowych działań można było od razu przystąpić do korzystania z jej metod. Która z metod zostanie wywołana, zależy od rodzaju przekazanych jej argumentów. Liczba i typy parametrów formalnych metody nazywa się jej sygnaturą typów (ang. type signature). Argumenty przekazywane w wywołaniu przeładowanej metody muszą być zgodne z sygnaturą typów jednej z jej wersji. Zdefiniowanie dwóch metod o takiej samej nazwie i takich samych sygnaturach typów jest niedozwolone. Na rodzaj wywoływanej metody ma wpływ wyłącznie sygnatura typów. Nie mają natomiast znaczenia nazwy parametrów formalnych ani typ powrotny metody. Dlatego błędem jest zdefiniowanie dwóch metod, które różnią się tylko typem zwracanych wartości lub nazwami parametrów. Operator new

43 Wykład Java ver Podobnie jak w przypadku tablic, zadeklarowanie zmiennej typu klasy powoduje przypisanie jej wartości null. Wartość ta, zdefiniowana jako odwołanie do obiektu typu Object, jest kompatybilna z wszystkimi innymi odwołaniami do klas. Różni się jednak, podobnie jak wartość false, od zera. Podana niżej przykładowa instrukcja deklaruje zmienną p typu Punkt i powoduje przypisanie jej wartości null. Punkt p; Operator new tworzy pojedynczy egzemplarz danej klasy i zwraca wartość odwołania do niego. Innymi słowy, operator ten rezerwuje pamięć wymaganą przez obiekt i zwraca adres, za pomocą którego można do tego obiektu uzyskiwać dostęp. Na przykład podana niżej instrukcja tworzy obiekt klasy Punkt i zapisuje wartość odwołania do niego w zmiennej p. Punkt p = new Punkt(); Jak wynika z podanych informacji, w Javie w inny sposób korzysta się z typów prostych i z typów klas. Mimo iż zmienna p z poprzedniego przykładu została zadeklarowana jako zmienna typu klasy, to nie jest obiektem, lecz jedynie odwołaniem do niego. Istnieje możliwość tworzenia wielu odwołań do tego samego obiektu. Na przykład podane niżej instrukcje tworzą jeden obiekt typu Punkt oraz dwa odwołania do niego. Punkt p = new Punkt(); Punkt p2 = p; Zapisanie wartości zmiennej p w zmiennej p2 nie powoduje zarezerwowania dodatkowej pamięci lub przekopiowania jakiejkolwiek części obiektu wskazywanego przez p. Przez przypisanie zmiennej p2 innej wartości, tak jak w podanym niżej przykładzie, można ją "odłączyć" od tego obiektu, nie wprowadzając do niego żadnej zmiany. Punkt p = new Punkt(); Punkt.p2 = p; p = null; Po wykonaniu ostatniej instrukcji zmienna p ma wartość null, ale zmienna p nadal wskazuje na obiekt utworzony za pomocą operatora new. Jeżeli obiekt nie jest wskazywany przez żadną zmienną, to Java automatycznie usuwa go, zwalniając całą zajmowaną przez niego pamięć. Działanie to nazywa się czyszczeniem pamięci (ang. garbage collection).

44 Wykład Java ver Dostęp do zmiennych i metod obiektów uzyskuje się za pomocą operatora oznaczanego kropką. Ogólna postać wyrażenia uzyskującego dostęp do zmiennej egzemplarzowej wygląda następująco: odwołanie_do_obiektu.nazwa_zmiennej; Zmienna znajdująca się z lewej strony operatora kropka musi być odwołaniem do obiektu utworzonego za pomocą operatora new, a identyfikator z prawej strony - nazwą jednej z jego zmiennych egzemplarzowych. Podany niżej fragment programu pokazuje przykład przypisywania zmiennym egzemplarzowym nowych wartości. p.x = 10; p.y = 20; W kolejnej przykładowej instrukcji operator kropka umożliwia odczytanie wartości zmiennych obiektu p i wyświetlenie ich na ekranie. System.out.println("x = " + p.x + ", y = " + p.y); Operator kropka umożliwia nie tylko uzyskiwanie dostępu do zmiennych egzemplarzowych klas, ale także wywoływanie ich metod. W poprzednim przykładzie utworzyliśmy pojedynczy obiekt, do którego odwoływały się dwie zmienne. Jednak języki zorientowane obiektowo, w tym Java, pozwalają tworzyć wiele obiektów tej samej klasy, z których każdy otrzymuje własny zestaw zmiennych egzemplarzowych. Dlatego zmiany wprowadzone do zmiennych jednego obiektu nie wpływają na postać pozostałych. Na przykład podany niżej program tworzy trzy obiekty klasy Punkt, umożliwiając reprezentowanie trzech różnych punktów. plik:dwapunkty.java class dwapunkty {public static void main(string args[]) {Punkt p1=new Punkt(10,55); Punkt p2=new Punkt(); Punkt p3=new Punkt(); Punkt3D h1=new Punkt3D(111,222); p3.a=11; p3.b=22; System.out.println("P1.a="+p1.a+", P1.b= "+ p1.b); System.out.println("P2.a="+p2.a+", P2.b= "+ p2.b); System.out.println("P3.a="+p3.a+", P3.b= "+ p3.b); int suma(int x,int y) { return x+y; dwapunkty()

45 Wykład Java ver {System.out.println("Dwa punkty konstruktor"); plik:punkt.java class Punkt { int a,b; Punkt(int x, int y) {a=x; b=y; Punkt() { this(99,-1); plik: Punkt3D.java class Punkt3D extends dwapunkty // podlasa klasy dwapunkty {Punkt3D(int l, int u) {super(); // wywołanie konstruktora nadklasy System.out.println("metoda suma ="+suma(l,u)); System.out.println("metoda super.suma ="+super.suma(l,u)); plik:go.bat javac -deprecation dwapunkty.java javac -deprecation Punkt.java javac -deprecation Punkt3D.java java dwapunkty Wynik zadziałania programu Dwa punkty konstruktor metoda suma =333 metoda super.suma =333 P1.a=10, P1.b= 55 P2.a=99, P2.b= -1 P3.a=11, P3.b= 22 Klasa dwapunkty zawiera metodę main(), potrzebną do jej uruchomienia. Trzeba pamiętać jednak o tym, że metoda main() musi występować tylko w jednej klasie programu - tej, od której rozpoczyna się jego działanie i której nazwę podaje się w wywołaniu interpretera Javy. W Javie nie istnieje mechanizm pozwalający na przekazywanie argumentów metod przez adres (ang. by reference). W językach C/C++ można przekazać funkcji na przykład wskaźnik do zmiennej typu int, która następnie może zostać przez tę funkcję zmodyfikowana. W Javie

46 Wykład Java ver wszystkie argumenty są przekazywane przez wartość (ang. by value), w konsekwencji czego metody nie mają dostępu do zmiennych, których wartości zostały przypisane ich parametrom. Również odwołania do obiektów są przekazywane przez wartość, co oznacza, że wywołane metody nie mogą zmieniać wartości zmiennych, które wskazują na obiekty. Dozwolona jest jednak modyfikacja zawartości obiektów, właśnie dzięki temu, że przekazywane są odwołania do nich. Dziedziczenie klas Drugim podstawowym mechanizmem programowania zorientowanego obiektowo jest dziedziczenie (ang. inheritance), umożliwiające tworzenie struktury drzewiastej wszystkich klas. Klasa potomna danej klasy dziedziczy wszystkie jej zmienne egzemplarzowe i metody, a oprócz tego definiuje własne, dodatkowe elementy. Można więc powiedzieć, że jest jej bardziej specjalistyczną wersją. Bezpośrednia klasa podrzędna danej klasy nazywa się jej podklasą (ang. subclass), a bezpośrednia klasa nadrzędna - nadklasą (ang. superclass). Tworzenie podklas jest bardzo prostą czynnością, podobną do tworzenia klas nie dziedziczących żadnej innej klasy. Jedyna różnica polega na tym, że za identyfikatorem podklasy umieszcza się słowo kluczowe extends oraz nazwę nadklasy. Jeśli jesteś programistą C/C++, to być może spodziewałeś się, że w tym miejscu nastąpi omówienie wielokrotnego dziedziczenia (ang. multiple inheritance), czyli jednoczesnego dziedziczenia większej liczby klas przez pojedynczą klasę. Wielokrotne dziedziczenie pozwala programiście łączyć atrybuty różnych klas, ale jednocześnie zmniejsza czytelność tekstu źródłowego i efektywność programu. Dlatego mechanizm ten nie został włączony do Javy. W większości przypadków, w których wskazane lub konieczne jest jego stosowanie, można go zastąpić użyciem interfejsów. Słowo kluczowe super umożliwia nie tylko wywoływanie konstruktora nadklasy, ale także każdej innej jej metody, można je więc traktować jako pełny odpowiednik słowa this. Słowo kluczowe this Java zawiera specjalne słowo kluczowe this, umożliwiające uzyskiwanie dostępu do zmiennych egzemplarzowych i metod bieżącej klasy, czyli klasy, w której słowo to występuje. Z technicznego punktu widzenia słowo this jest odwołaniem do bieżącej klasy i może być użyte w każdym miejscu, w którym dozwolone jest użycie dowolnego innego odwołania. Istnienie słowa kluczowego this może wydawać się w pierwszej chwili niepotrzebne, gdyż, jak stwierdziliśmy wcześniej, metody mogą uzyskiwać dostęp do zmiennych

47 Wykład Java ver egzemplarzowych swojej klasy bezpośrednio lub za pmocą słowa kluczowego super, tak jakby były one ich zmiennymi lokalnymi. W taki sam sposób można wywoływać wszystkie metody zadeklarowane w tej samej klasie. Jednak słowo this pozwala użyć tych samych nazw w odniesieniu do parametrów formalnych oraz do zmiennych egzemplarzowych, co nieraz upraszcza tekst źródłowy. Wówczas dostęp do parametrów uzyskuje się bezpośrednio, a dostęp do zmiennych egzemplarzowych za pomocą odwołania this.. Między słowem this a identyfikatorem zmiennej umieszcza się operator zapisywany za pomocą kropki. Słowa kluczowego this można także używać do wywoływania metod. Jedyna sytuacja, w której korzystanie z tej właściwości Javy ma sens, występuje wtedy, gdy dana klasa zawiera kilka konstruktorów (są one przeładowane) i jeden z nich wywołuje inny. Często zastosowanie takiego rozwiązania ulepsza wygląd tekstu źródłowego. Słowo kluczowe this traktuje się w tym kontekście tak samo, jak nazwę metody. Oznacza to, że umieszcza się za nim w nawiasach listę jego parametrów. plik :BaseClass.java class BaseClass{ int i=100; public static void main(string args[]){ int i; BaseClass baza= new BaseClass(); Pochodna pochodna=new Pochodna(); i=400; System.out.println(""); System.out.println(" main for BaseClass"); System.out.println("i = "+i); System.out.println("baza.i = "+ baza.i); System.out.println("pochodna.i = "+ pochodna.i); System.out.println("((BaseClass)pochodna).i = "+ ((BaseClass)pochodna).i); plik:pochodna.java class Pochodna extends BaseClass{ int i=200; Pochodna() { int i; i=300; System.out.println(" konstruktor dla Pochodnej"); System.out.println("i ="+ i); System.out.println("this.i = "+this.i); System.out.println("super.i = "+super.i);

48 Wykład Java ver Przykrywanie i dynamiczne rozdzielanie metod W języku C++ funkcje klasy bazowej zadeklarowane jako wirtualne mogą zostać przykryte (ang. overridden) przez funkcje klas pochodnych. W Javie istnieje podobny mechanizm, ale nie wymaga on stosowania słowa kluczowego virtual; słowo to nie jest nawet w tym języku zdefiniowane. Każda metoda podklasy Javy, która ma taką samą nazwę i taką samą listę parametrów, co odpowiadająca jej metoda nadklasy, automatycznie przykrywa ją. Tak więc wszystkie metody Javy są z założenia wirtualne, chyba że w sposób jawny zostało w programie określone inaczej. Przykrycie metody przez podklasę powoduje, że odpowiadająca jej metoda z nadklasy przestaje być dostępna. Oznacza to, że każde wywołanie przykrytej metody przez obiekt podklasy powoduje wykonanie jej wersji zdefiniowanej w tej podklasie. Przyjrzyjmy się na przykład następującemu programowi plik: AA.java class AA {int i,j; AA(int a, int b) {i=a; j=b;

49 Wykład Java ver void Widok() {System.out.println("Zmienne i,j: "+i+" "+j); plik: BB.java class BB extends AA {int k; BB(int a, int b, int c) {super(a,b); k=c; /* Wyświetlanie wartości zmiennej k - metoda przykrywająca metodę Widok() z klasy AA*/ void Widok() {System.out.println("Zmienna k: "+k); plik: Przykrywanie.java class Przykrywanie {public static void main(string args[]) {BB ob=new BB(1,2,3); ob.widok(); // wywołanie metody Widok() z klasy BB go.bat javac -deprecation AA.java javac -deprecation BB.java javac -deprecation Przykrywanie.java java Przykrywanie Wynik zadziałania programu Zmienna k: 3 Zapobieganie przykrywania metod Mimo iż możliwość przykrywania metod jest jedną z najważniejszych cech Javy, to jednak zdarza się, że wykonywanie tego działania jest niepożądane. Aby uniemożliwić przykrycie

50 Wykład Java ver metody, na początku jej deklaracji należy umieścić słowo kluczowe final, czyli zadeklarować ją jako metodę finalną. Niżej zostało to zilustrowane na przykładzie: class A { final void lala() { System.out.println("To jest metoda finalna."); class B extends A { void lala() { // Błąd! Tej funkcji nie wolno przykrywać! System.out.println("Instrukcja niedozwolona!"); Ponieważ metoda lala() została zadeklarowana w klasie A ze słowem kluczowym final, nie można jej przykryć w klasie B. Próba wykonania takiego działania powoduje wygenerowanie błędu kompilacji. Warto również wiedzieć, że metody finalne mogą zawierać instrukcje wewnętrzne (ang. inline code), pozwalające uniknąć wydłużenia czasu działania programu spowodowanego koniecznością zastosowania typowego mechanizmu wywołania funkcji i pobrania jej wartości (pod tym względem metody final Javy są podobne do funkcji inline C++). Zapobieganie dziedziczeniu Niektóre z tworzonych klas nie powinny być dziedziczone. Aby temu zapobiec, należy zadeklarować klasę jako finalną, czyli poprzedzić jej deklarację słowem kluczowym final. Wszystkie metody klasy finalnej są również finalne. Jak można się domyślić, niedozwolone jest jednoczesne użycie słów kluczowych abstract i final w deklaracji klasy, gdyż każda klasa abstrakcyjna jest niepełna, a jej metody są implementowane w podklasach. Niżej został pokazany schematyczny przykład definicji klasy finalnej: final class A{ //... class B extends A{ // Błąd! Klasy A nie wolno dziedziczyć!

51 Wykład Java ver Jak wynika z komentarzy, klasa B nie może dziedziczyć klasy A, ponieważ ta ostatnia została zadeklarowana jako klasa finalna. Tworzenie stałych symbolicznych Trzecie zastosowanie słowa kluczowego final polega na definiowaniu zmiennych będących odpowiednikami stalych symbolicznych, czyli oznaczanych za pomocą nazwy (ang. named constants). Zmienne, których deklaracja zawiera słowo kluczowe final, nie mogą być w programie modyfikowane. Wynika stąd, że deklaracje zmiennych finalnych powinny zawierać ich inicjalizację (w tym zastosowaniu słowo final jest podobne do słowa const języków C/C++). Na przykład instrukcja final int LICZNIK=1000; tworzy stałą Licznik o wartości Metody i klasy abstrakcyjne Programiści C++ wiedzą, że niektóre funkcje wirtualne definiowane w klasach bazowych nie są w żaden sensowny sposób zaimplementowane. Funkcje takie są zwykle deklarowane z użyciem słów kluczowych virtual, co oznacza, że muszą być przykrywane w klasach pochodnych. Innymi słowy, klasy bazowe określają jedynie interfejs czystych funkcji wirtualnych, natomiast ich implementacja jest definiowana osobno przez każdą klasę pochodną. Podobne funkcje można również tworzyć w Javie, ale tutaj nazywają się one metodami abstrakcyjnymi (ang. abstract methods). Metody abstrakcyjne deklaruje się z użyciem specyfikatora abstract i nie określa się dla nich implementacji. Jeżeli więc nadklasa zawiera metodę abstrakcyjną, to każda podklasa musi ją przykryć - korzystanie z wersji zdefiniowanej w nadklasie nie jest możliwe, gdyż taka wersja nie istnieje. Ogólna postać deklaracji metody abstrakcyjnej wygląda następująco: abstract typ nazwa(lista_parametrów); Jak widać, metoda abstrakcyjna nie zawiera głównej części (poza deklaracją nie ma żadnych instrukcji). Każda klasa zawierająca jedną lub więcej metod abstrakcyjnych nazywa się klasą abstrakcyjną (ang. abstract class). Aby zadeklarować klasę abstrakcyjną, na początku deklaracji, przed słowem kluczowym class należy umieścić słowo abstract. Niżej został podany bardzo prosty przykład zastosowania klasy i metody abstrakcyjnej: plik kwadrat.java abstract class kwadrat // klasa abstrakcyjna {abstract int kw(int g);//metoda abstrakcyjna

52 Wykład Java ver plik kw2.java class kw2 extends kwadrat { int kw(int i){return i*i; /* klasa kw2 musi zawierać implementację metody kw. w przeciwnym wypadku pojawi się błąd kompilacji*/ plik wynik.java class wynik {public static void main(string args[]) {kw2 ob=new kw2(); System.out.println("Kwadrat liczby 10: "+ob.kw(10)); Wynik zadziałania programu: Kwadrat liczby 10: 100 Ponieważ metoda kw() jest metodą abstrakcyjną, również klasa Kwadrat musi być abstrakcyjna. Oznacza to, że klasa kw2, stanowiąca rozszerzenie klasy Kwadrat musi zawierać implementację metody kw. Niezastosowanie się do tego wymogu spowodowałoby wygenerowanie błędu kompilacji (zgodnie z uwagami zamieszczonymi w komentarzach programu). Aby się o tym przekonać, wystarczy usunąć główną część z metody kw należącej do klasy kw2 Nie istnieje możliwość tworzenia obiektów klas abstrakcyjnych. Innymi słowy, niedozwolone jest tworzenie egzemplarzy klasy abstrakcyjnej za pomocą operatora new. Łatwo jest zrozumieć przyczynę takiego ograniczenia: obiekty klas abstrakcyjnych byłyby bezużyteczne, ponieważ zawierałyby niezdefiniowane metody. Inne ograniczenia mówią, że nie wolno deklarować abstrakcyjnych konstruktorów oraz abstrakcyjnych metod statycznych. Każda podklasa klasy abstrakcyjnej musi implementować wszystkie metody abstrakcyjne nadklasy, chyba że sama została zadeklarowana jako abstrakcyjna. Metody i zmienne statyczne Nieraz trzeba utworzyć metodę, która byłaby dostępna bez konieczności tworzenia obiektów jej klasy. W tym celu należy ją zadeklarować ze słowem kluczowym static, tak jak w przypadku metody main(). Metody statyczne mogą wywoływać bezpośrednio tylko inne metody statyczne i nie mogą korzystać ze słów kluczowych this i super. Istnieje również możliwość tworzenia zmiennych statycznych, ale należy pamiętać o tym, że w istocie są one zmiennymi globalnymi, dostępnymi z każdego miejsca programu.

53 Wykład Java ver Jeżeli inicjalizacja zmiennych statycznych wymaga wykonania dodatkowych instrukcji, to można je umieścić w bloku o nazwie static, który jest wykonywany tylko raz, podczas pierwszego ładowania klasy. Podana niżej klasa o nazwie stat zawiera metodę statyczną metoda(int x), dwie zmienne statyczne oraz blok inicjalizacyjny static. class stat {static int a=3; static int b; static void metoda(int x) {System.out.println("x= "+x); System.out.println("a= "+a); System.out.println("b= "+b); stat{system.out.println(" Inicjalizacja bloku statycznego"); b=a*4; public static void main(string args[]) {metoda(50); Po pierwszym załadowaniu klasy wykonywane są instrukcje z deklaracjami zmiennych a i b, a bezpośrednio po nich - blok static, wyświetlający odpowiedni komunikat oraz przypisujący zmiennej b wynik wyrażenia a * 4, czyli liczbę 12. Następnie interpreter wywołuje metodę main(), która wywołuje metodę statyczną (), przekazując jej argument o wartości 50. Pierwsza instrukcja z metodą println() wyświetla wartość zmiennej lokalnej (parametru formalnego) x, a dwie następne - wartości zmiennych statycznych a i b. In formacje wyświetlane przez ten program wyglądają następująco: Wynik zadziałania programu: Inicjalizacja bloku statycznego x= 50 a= 3 b= 12 Jak już wiemy, korzystanie z metod i zmiennych statycznych nie wymaga tworzenia obiektów ich klas. Wykonuje się to podobnie jak w przypadku stosowania pozostałych,elementów klas, z tym że przed operatorem "kropka" nie umieszcza się nazwy obiektu lecz nazwę klasy. W taki właśnie sposób niejednokrotnie wywoływaliśmy w programach przykładowych metody

54 Wykład Java ver standardowe Javy. Jak widać, stanowią one odpowiednik funkcji globalnych występujących w takich językach, jak C i C++, lecz mają w porównaniu z nimi tę zaletę, że ich nazwy są definiowane względem danej klasy. Dzięki temu nie jest możliwe przypadkowe zdefiniowanie funkcji, która by miała tę samą nazwę, co jedna z istniejących już funkcji bibliotecznych. Podane uwagi odnoszą się również do zmiennych statycznych. Pakiety i interfejsy Pakiety umożliwiają grupowanie klas i nadawanie im takich samych nazw w różnych grupach. Można na przykład zdefiniować klasę o nazwie List i umieścić ją w nowym pakiecie, nie obawiając się, że wystąpi konflikt między tą a inną, istniejącą już klasą o takiej samej nazwie. Podobnie jak klasy, pakiety tworzą strukturę hierarchiczną.. Aby można było korzystać z klas danego pakietu, trzeba go zaimportować. Interfejs jest specyfikacją zestawu metod, które w tworzonej klasie trzeba zaimplementować. Interfejsy są więc podobne do klas abstrakcyjnych, ale różnią się od nich tym, że nie zawierają ani jednej definicji metody. Dla programisty istotny jest również fakt, że interfejsy można wielokrotnie implementować, czyli że pojedyncza klasa może dziedziczyć wiele interfejsów (Pamiętej! wielokrotne dziedziczenie klas jest w Javie zabronione). Pakiety Wszystkie identyfikatory, których używaliśmy dotychczas do tworzenia klas, należały do tej samej przestrzeni nazw (ang. name space). Oznacza to, że każda klasa musiała mieć inną nazwę, gdyż w przeciwnym wypadku wystąpiłby między nimi konflikt. Brak mechanizmu umożliwiającego zarządzanie przestrzenią nazw spowodowałby, że już w krótkim czasie zabrakłoby nam nazw, które by się nie powtarzały, a jednocześnie w sensowny sposób opisywały tworzone klasy. Jeszcze trudniej dochodziłoby do kompromisów zawieranych między różnymi programistami. Wyobraźmy sobie na przykład sytuację, w której tysiące programistów na całym świecie próbuje uzgodnić nazwy klas występujących w przygotowywanych przez nich programach dla Internetu. Na szczęście, Java zawiera mechanizm umożliwiający dzielenie przestrzeni nazw na mniejsze fragmenty. Tworzy on pakiety i pozwala nie tylko używać powtarzających się nazw klas, ale także określać zakres ich elementów. Można na przykład utworzyć klasę, której zmienne i metody będą dostępne tylko dla innych klas należących do tego samego pakietu. Każdy plik z

55 Wykład Java ver rozszerzeniem java może składać się z czterech części, z których do tej pory wykorzystywaliśmy tylko jedną. Ogólna postać pliku źródłowego Javy wygląda następująco: pojedyncza instrukcja package (część opcjonalna), dowolna liczba instrukcji import (część opcjonalna), pojedyncza deklaracja klasy publicznej, dowolna liczba deklaracji klas prywatnych (część opcjonalna). Na samym początku pliku źródłowego Javy może znajdować się instrukcja package, informująca kompilator o nazwie pakietu, do którego mają należeć wszystkie zdefiniowane niżej klasy. Pominięcie jej powoduje, że klasy z danego pliku są umieszczane w pakiecie domyślnym, nie posiadającym żadnej nazwy. Ogólna postać instrukcji package wygląda następująco: package nawa_pakietu1[.nawa_pakietu2[.nawa_pakietu3]]; Zwróć uwagę, że można tworzyć strukturę hierarchiczną pakietów, oddzielając ich nazwę za pomocą kropki. Struktura pakietów musi być skorelowana ze strukturą katalogów na dysku. Na przykład wszystkie pliki źródłowe z definicjami klas należących do pakietu MyPackage trzeba umieścić w katalogu MyPackage, natomiast pliki zawierające instrukcję package jawa.awt.image muszą się znajdować w katalogu java\awt\image, java\awt\image lub java:awt:image, w zależności od używanego systemu operacyjnego. Należy pamiętać o tym, że w Javie rozróżniane są małe i duże litery, zarówno w nazwach klas, jak i w nazwach plików i katalogów. Uwaga: Katalog główny struktury katalogów odpowiadających poszczególnym pakietom określa się za pomocą zmiennej środowiskowej CLASSPATH. Ponieważ dozwolone jest podanie większej liczby katalogów, istnieje możliwość umieszczania pakietów w różnych miejscach. Kompilowanie i uruchamianie klas należących do pakietów Pakiety pozwalają rozwiązać wiele problemów związanych ze sterowaniem dostępem do klas i podziałem ich przestrzeni nazw. Z drugiej jednak strony, stwarzają one pewne trudności podczas kompilowania i uruchamiania programów. Wszystkie klasy, które tworzyliśmy do tej pory, zapisywaliśmy w domyślnym pakiecie bez nazwy. Dzięki temu mogliśmy w prosty sposób kompilować pliki źródłowe i uruchamiać ich wersje bajtowe za pomocą interpretera przez podawanie ich nazw w wierszu poleceń. Było tak dlatego, że wśród katalogów

56 Wykład Java ver określonych za pomocą zmiennej środowiskowej CLASSPATH znajdował się bieżący katalog roboczy, oznaczany kropką. Sytuacja nieco komplikuje się wówczas, gdy tworzone klasy umieszczane są w osobnych pakietach. Jak już wiemy, ich struktura powinna pokrywać się ze strukturą katalogów na dysku. Oznacza to, że na przykład klasy pakietu test powinny znajdować się w katalogu test. Ta zasada wydaje się raczej oczywista. Na tym jednak problemy się nie kończą. Powiedzmy, że w katalogu głównym bieżącego dysku utworzyliśmy katalog test i umieściliśmy w nim plik PackTestjava, zawierający definicję klasy PackTest z pakietu test. Niestety, kiedy spróbowaliśmy ją uruchomić za pomocą polecenia java PackTest, interpreter wyświetlił komunikat can't find class PackTest (nie mogę znaleźć klasy PackTest). Również wpisanie polecenia java test.packtest, określającego pakiet, do którego należy klasa PackTest, nie zakończyło się pomyślnie - znów pojawił się komunikat stwierdzający, że kompilator nie może jej odnaleźć. Wyjaśnienie tej zagadki kryje się w tym, że interpreter rozpoczyna szukanie klas od katalogów określonych za pomocą zmiennej środowiskowej CLASSPATH. Jeżeli zmienna ma wartość.;c:\ java\classes (co jest najbardziej prawdopodobne), to wpisanie polecenia java PackTest spowoduje, że interpreter będzie najpierw szukał pliku PackTest.class w bieżącym katalogu roboczym, a następnie w katalogu C:\ java\classes. Podobnie, polecenie java test.packtest doprowadzi do uruchomienia klasy PackTest tylko wtedy, gdy jej kod bajtowy będzie znajdować się w podkatalogu test bieżącego katalogu roboczego lub w katalogu C: java\classes\test. Powstały problem można więc rozwiązać na dwa sposoby. Pierwszy, niewarty polecenia, polega na przejściu do katalogu C:\test i wpisaniu polecenia java PackTest. Drugi sposób jest dużo lepszy i polega na takim zmodyfikowaniu zmiennej środowiskowej CLASSPATH, aby wskazywała również na początek struktury katalogów, w której będziemy umieszczać nasze programy Javy, i uruchamianiu ich z podawaniem nazw pakietów. W opisywanym przypadku zmienną CLASSPATH trzeba ustawić na.;c:\ java\classes;c:\. Zwykle jednak plików Javy nie zapisuje się w katalogu głównym, lecz w innym, specjalnie do tego celu utworzonym. Zakładając, że nazywa się on MyJava, zmienna CLASSPATH powinna mieć wartość; C:\java\classes;C:\MyJava (plik PackTest.java powinien się wówczas znajdować w katalogu C: \MyJava\test).

57 Wykład Java ver Importowanie klas z innych pakietów Między instrukcją package a pierwszą definicją klasy mogą znajdować się w pliku źródłowym instrukcje import. Biorąc pod uwagę fakt, że umieszczanie klas w pakietach pozwala uniknąć konfliktu występującego między ich nazwami, nietrudno zrozumieć, dlaczego ani jedna wbudowana klasa Javy nie znajduje się w domyślnym pakiecie bez nazwy. Jednak konieczność wpisywania dla każdej używanej klasy jej pełnej ścieżki, czyli nazw wszystkich pakietów oddzielonych kropką, sprawiałaby programistom dużo kłopotów. Dlatego Java zawiera słowo kluczowe import, pozwalające określać klasy, do których można uzyskiwać dostęp przez podanie samej ich nazwy. Zostało ono wprowadzone jedynie w celu ułatwienia programistom pracy i jego stosowanie nie jest konieczne do poprawnego skompilowania programu. Jeżeli jednak liczy on dużo instrukcji i odwołuje się do klas należących do wielu pakietów, to słowo import w sposób istotny upraszcza tekst źródłowy. Ogólna postać instrukcji import wygląda następująco: import nazwa-pakietu1[.nazwa-pakietu2]. (nazwa_klasy *); nazwa_pakietu1 oznacza nazwę pakietu najwyższego poziomu, nazwa_pakietu2 opcjonalną nazwę pakietu drugiego poziomu itp. Maksymalna głębokość struktury pakietów jest nieograniczona. Na końcu instrukcji import trzeba podać nazwę jednej ze znajdujących się w nim klas lub gwiazdkę, oznaczającą zaimportowanie wszystkich klas należących do danego pakietu. Oto przykład użycia obu postaci instrukcji import: import java.util.date; import java.io; OSTRZEŻENIE: Umieszczenie gwiazdki w większej liczbie instrukcji import powoduje wydłużenie czasu kompilowania programu, szczególnie wtedy, gdy importowane pakiety zawierają dużo klas. Wynika to z faktu, że po napotkaniu odwołania do klasy, która nie należy do bieżącego pakietu i nie została zaimportowana przez podanie jej nazwy w instrukcji import, kompilator szuka jej we wszystkich pakietach zaimportowanych w całości. Dlatego nieraz lepiej jest importować pojedyncze klasy. Warto jednak pamiętać o tym, że stosowanie gwiazdki nie ma żadnego wpływu na sposób i szybkość działania skompilowanego programu. Podany niżej przykład pokazuje sposób korzystania z zaimportowanych klas: import java.util.*; class MojeDane extends Date {

58 Wykład Java ver Gdyby pominięto instrukcję import, deklaracja klasy MojeDane musiałaby wyglądać następująco: class MojeDane extends java.util.date { Można również importować klasy, które mają taką samą nazwę i występują w różnych pakietach, ale i tak trzeba się do nich odwoływać przez podanie ich ścieżek, czyli pełnej hierarchii pakietów. Wszystkie wbudowane, standardowe klasy Javy należą do pakietu o nazwie java, natomiast pakiet java.lang zawiera podstawowe funkcje językowe. Ponieważ bez tych funkcji Java jest praktycznie bezużyteczna, to w przeciwieństwie do samodzielnie tworzonych klas, klasy z pakietu java.lang są importowane przez kompilator automatycznie. Tak więc każdy plik źródłowy jest kompilowany w taki sposób, jakby na jego początku znajdowała się instrukcja import java.lang.*; Ochrona dostępu do elementów klas W Javie istnieją dwa sposoby określania zakresu zmiennych i metod. Pierwszy z nich polega na odpowiednim rozmieszczaniu elementów programów w klasach i pakietach. Na przykład wszystkie zmienne egzemplarzowe i metody należące do określonej klasy są dostępne dla wszystkich innych jej elementów. Wszystkie pozostałe klasy można podzielić na następujące cztery kategorie: podklasy znajdujące się w tym samym pakiecie, inne klasy znajdujące się w tym samym pakiecie, podklasy znajdujące się w innych pakietach, inne klasy znajdujące się w innych pakietach. Drugi sposób określania zakresu zmiennych i metod polega na stosowaniu znanych z języka C++ modyfikatorów public, private i protected oraz domyślnego poziomu dostępu, nie oznaczanego żadnym słowem kluczowym. Tabela pokazuje dostępność poszczególnych rodzajów elementów typów Javy w wymienionych wyżej kategoriach klas. Kolumny odpowiadają modyfikatorom, za pomocą których można deklarować elementy klas, natomiast wiersze - kategorie klas, w których istnieją instrukcje odwołujące się do elementów. Słowa znajdujące się na przecięciu poszczególnych wierszy i kolumn określają dostępność danego rodzaju elementu w określonym miejscu programu. Na przykład elementy chronione (protected) są widoczne we wszystkich podklasach oraz klasach należących do tego samego

59 Wykład Java ver pakietu, natomiast prywatne chronione (private protected) - w danej klasie oraz we wszystkich jej podklasach. Specyfikatory dostępu Kategoria klas Prywatne Bez modyfikatora Prywatne Chronione Publiczne chronione Ta sama klasa TAK TAK TAK TAK TAK Podklasy znajdujące się w tym samym pakiecie NIE TAK TAK TAK TAK Inne klasy znajdujące się w tym samym pakiecie Podklasy znajdujące się w innych pakietach Inne klasy znajdujące się w innych pakietach NIE TAK NIE TAK TAK NIE NIE TAK TAK TAK NIE NIE NIE NIE TAK Mimo iż zawartość tabeli wygląda dość skomplikowanie, to jednak można podać kilka ogólnych zasad ułatwiających jej zrozumienie i stosowanie. Słowo kluczowe public udostępnia dany element wszystkim klasom programu, natomiast słowo private zabrania dostępu wszystkim klasom z wyjątkiem klasy, w której dany element występuje. Elementy zadeklarowane bez żadnego modyfikatora są dostępne dla wszystkich klas danego pakietu. Jeżeli element klasy ma być widoczny dodatkowo we wszystkich jej podklasach należących do innych pakietów, to trzeba go zadeklarować za pomocą słowa kluczowego protected. Wreszcie, element klasy, który ma być widoczny tylko w jego klasie oraz wszystkich jej podklasach, niezależnie od ich położenia, powinien zostać zadeklarowany z użyciem modyfikatorów private protected. OSTRZEŻENIE: Jeśli jesteś programistą C++, to zwróć uwagę, że modyfikator Javy protected ma inne znaczenie niż w C++; jest raczej podobny do słowa kluczowego friend. Odpowiednikiem modyfikatora protected z języka C++ jest w Javie para słów private protected. Interfejsy Interfejsy Javy umożliwiają dynamiczne rozróżnianie metod w czasie działania programu. Jeżeli jedna metoda wywołuje drugą, należącą do innej klasy, to obie klasy muszą istnieć podczas kompilacji. W przeciwnym razie kompilator nie mógłby sprawdzić, czy liczba i typy przekazywanych argumentów są zgodne z sygnaturą

60 Wykład Java ver typów wywoływanej metody. Wymaganie to ogranicza w znacznym stopniu możliwości rozszerzania klas i nadaje im charakter statyczny. W tego rodzaju systemach większość funkcji jest realizowana przez klasy znajdujące się na wysokim poziomie hierarchii klas, tak aby były one dostępne dla jak największej liczby podklas. Musi więc istnieć mechanizm umożliwiający oddzielenie definicji metod od struktury ich dziedziczenia. Interfejsy przypominają klasy, ale nie występują w nich zmienne egzemplarzowe, a ich metody są pozbawione części głównej. Mówiąc inaczej, interfejsy określają sposób korzystania z metod, ale nie zawierają ich implementacji (definicji). Każda klasa może implementować dowolną liczbę interfejsów. Implementacja interfejsu jest podobna do dziedziczenia klasy i polega na zdefiniowaniu wszystkich zadeklarowanych w nim metod, oczywiście z zachowaniem ich sygnatur typów. Ponieważ hierarchia interfejsów jest niezależna od hierarchii klas, wiele nie powiązanych ze sobą klas może dziedziczyć ten sam interfejs. Stanowi to jedną z głównych korzyści odnoszonych ze stosowania interfejsów. UWAGA: Implementowanie interfejsów umożliwia rozwiązywanie problemów, które w języku C++ wymagałyby wielokrotnego dziedziczenia klas. Interfejsy mają czytelniejszą postać niż klasy i są od nich bardziej uniwersalne, gdyż nie zawierają zmiennych egzemplarzowych i definicji metod. Słowo kluczowe interface. Ogólna postać definicji interfejsu jest podobna do definicji klasy i wygląda następująco: interface nazwa { typ nazwa_metody1(lista-parametrów); typ nazwa_metody2(lista-parametrów);... typ nazwa_metodyn(lista-parametrów); typ nazwa_zmiennej_1 = wartość; typ nazwa_zmiennej_2 = wartość; typ nazwa_zmiennej_n = wartość; Słowo nazwa oznacza dowolny identyfikator i jest odpowiednikiem nazwy klasy. Zwróć uwagę, że żadna z metod nie ma części głównej, czyli bloku instrukcji umieszczonego w nawiasach klamrowych; za nawiasem zamykającym listę

61 Wykład Java ver parametrów występuje średnik. Oprócz metod interfejs może zawierać zmienne finalne, czyli odpowiedniki stałych z innych języków programowania. Podany niżej przykładowy interfejs zawiera metodę o nazwie dom(), pobierającą jeden parametr typu inf. interface dane { void dom(int param); Słowo kluczowe implements Ogólna postać definicji klasy implementującej jeden lub więcej interfejsów wygląda następująco ( jest to rozszerzenie definicji podanej wcześniej): class nazwa_klasy [extends nazwa_nadkląsy] [implements interfejs0 [,interfejs1...]] { główna_część_klasy Jeżeli klasa dziedziczy więcej niż jeden interfejs, to ich nazwy oddziela się przecinkami. Wszystkie metody implementujące interfejsy muszą być zadeklarowane ze słowem kluczowym public. Dozwolone jest deklarowanie zmiennych jako odwołań od interfejsów i odwoływanie się za ich pomocą do egzemplarzy wszystkich klas, które dany interfejs implementują. Wersja metody wywoływanej za pomocą tego rodzaju zmiennej jest określana na podstawie typu obiektu, na który zmienna ta w danej chwili wskazuje. Metody są wybierane dynamicznie w czasie przebiegu, co pozwala tworzyć implementacje interfejsów później niż klasy, które z nich korzystają. Dla wywołującej metody nie są istotne szczegóły dotyczące działania metody wywoływanej, lecz rodzaj wykonywanego przez nią zadania oraz sposób jej wywołania. OSTRZEŻENIE: Ponieważ odszukiwanie metod w czasie działania programu wpływa negatywnie na szybkość jego działania, to w miejscach, w których ma ona decydujące znaczenie, należy unikać deklarowania zmiennych jako odwołań od interfejsów. Zmienne w interfejsach

62 Wykład Java ver Interfejsów można także używać do deklarowania często wykorzystywanych zmiennych finalnych (stałych). Działanie to przypomina tworzenie plików nagłówkowych C++ zawierających instrukcje #define lub enum. Aby w tworzonej klasie uzyskać dostęp do zmiennych należących do danego interfejsu, należy go zaimplementować. Jeżeli nie zawiera on żadnej metody, to wystarczy umieścić jego nazwę za słowem implements, występującym w deklaracji klasy. Wówczas interfejs nie jest w zasadzie implementowany, lecz raczej importowany. Najlepszym momentem na wyłapanie błędu jest kompilacja jeszcze przed próbą uruchomienia programu. Jednak nie wszystkie błędy można wykryć podczas kompilacji. Pozostałe problemy muszą być obsłużone podczas wykonania programu przez jakiś mechanizm, pozwalający sprawcy błędu przekazać odpowiednią informację do odbiorcy, który będzie wiedział, jak ma rozwiązać zaistniałą sytuację. W C i innych starszych językach stosowano kilka takich mechanizmów. Jednak nie były one częścią języka, tylko zostały ustanowione przez konwencję. Najczęściej polegały na zwróceniu specjalnej wartości lub ustawieniu znacznika. Odbiorca musiał sprawdzać wartość lub znacznik, aby stwierdzić, czy coś poszło nie tak, jak powinno. Jednak z upływem lat odkryto, że programiści, którzy używają takich bibliotek, mają skłonność do megalomanii: "tak, takie błędy mogą zdarzać się innym, ale nigdy w moim kodzie". Nic dziwnego więc, że zaprzestali sprawdzania sytuacji wyjątkowych (a zdarzało się tak, że sytuacje wyjątkowe były zbyt banalne, żeby ktoś nawet pomyślał, by je sprawdzać)'. Z drugiej strony, jeśli ktoś był na tyle dokładny, by sprawdzać wystąpienie błędu przy każdym wywołaniu metody, to jego kod szybko zmieniał się w nieczytelny koszmar. Rozwiązaniem tego problemu jest odrzucenie przypadkowości w obsługiwaniu błędów i wymuszenie pewnych zachowań. Pomysł ten ma już długą historię, ponieważ próby implementacji obsługi sytuacji wyjątkowych (ang. exception handling) sięgają systemów operacyjnych z lat 60. czy nawet znanego z BASIC-a "on error goto". Ale obsługa wyjątków w C++ była oparta na Adzie, a Java opiera się głównie na C. Słowo "wyjątek" występuje tu w znaczeniu: "przyjmuję możliwość wystąpienia wyjątku od tego". W momencie wystąpienia problemu możemy nie wiedzieć, co z nim zrobić, ale wiemy, że nie można go beztrosko zignorować. Trzeba się zatrzymać, a ktoś gdzieś musi wymyślić, co robić dalej. W danym kontekście brakuje informacji potrzebnych do rozwiązania

63 Wykład Java ver problemu. Zatem przekazujemy problem do szerszego kontekstu, gdzie znajdzie się ktoś z kwalifikacjami odpowiednimi do podjęcia odpowiedniej decyzji (podobnie jak w strukturach władzy). class Raz { String m_snazwa= "Raz"; String s() { return "1"; class Dwa extends Raz { String m_snazwa= "Dwa"; String s() { return "2"; class Trzy extends Dwa { String m_snazwa= "Trzy"; String s() { return "3"; void test() { java.io.printwriter stdout =new java.io.printwriter(system.out,true); stdout.println("s()=\t\t\t"+s()); stdout.println("m_snazwa=\t\t"+m_snazwa); stdout.println("..."); stdout.println("super.s()=\t\t"+super.s()); stdout.println("super.m_snazwa=\t\t"+super.m_snazwa); stdout.println("..."); stdout.println("((dwa)this).s()=\t"+((dwa)this).s()); stdout.println("((dwa)this).m_snazwa=\t"+((dwa)this).m_snazwa); stdout.println("..."); stdout.println("((raz)this).s()=\t"+((raz)this).s()); stdout.println("((raz)this).m_snazwa=\t"+((raz)this).m_snazwa); public class SuperTest { public static void main(string args[]) throws Exception { //Tworzymy nowy obiekt trzy typu Trzy Trzy trzy = new Trzy(); //Wywołanie metody test() trzy.test(); //Zatrzymanie aplikacji do czasu nacisnięcia klawisza Enter pauza(); static void pauza() throws Exception { System.out.print("Nacisnij Enter..."); System.in.read();

64 Wykład Java ver Sytuacja wyjątkowa to problem, który wstrzymuje wykonywanie metody lub bloku. Ważne jest, by oddzielić sytuację wyjątkową od zwykłego problemu, to jest takiego, kiedy w aktualnym kontekście istnieje dość przesłanek, by jakoś poradzić sobie z trudnościami. W sytuacji wyjątkowej nie można kontynuować przetwarzania, ponieważ w aktualnym kontekście nie ma dostępu do informacji koniecznej do rozwiązania problemu. Wszystko, co można zrobić, to wyjść z aktualnego kontekstu i przekazać problem do kontekstu wyżej. Tak się właśnie dzieje, kiedy zgłaszany jest wyjątek. Prostym przykładem jest dzielenie. Jeśli próbujemy dzielić przez zero, to warto się upewnić, że takie dzielenie nie nastąpi. Ale co oznacza zerowy mianownik przy danym zastosowaniu naszej metody? Być może, w kontekście danego problemu, wiadomo, co zrobić z zerowym mianownikiem. Jeśli jednak jest to wartość nieoczekiwana, nie można z nią nic zrobić i zamiast iść dalej, trzeba zgłosić wyjątek. Kiedy zgłaszany jest wyjątek, dzieje się kilka rzeczy. Po pierwsze, w taki sam sposób, jak każdy obiekt Javy, tworzony jest obiekt wyjątku - odkładany na stercie poprzez instrukcję new. Aktualna ścieżka wykonania (ta, która nie może być kontynuowana) jest przerywana i obiekt wyjątku jest wyrzucany z aktualnego kontekstu. W tym momencie sterowanie przejmuje mechanizm obsługi wyjątków i zaczyna szukać miejsca odpowiedniego do podjęcia dalszego wykonywania programu. Tym odpowiednim miejscem jest procedura obsługi wyjątku. Jej zadaniem jest wybrnąć z problemu tak, żeby program mógł spróbować innego rozwiązania lub po prostu kontynuować wykonanie, ignorując błąd. Jako prosty przykład zgłaszania wyjątku rozważmy obiekt o nazwie t. Może się zdarzyć, że otrzymamy uchwyt, który nie został zainicjowany, więc chcielibyśmy to sprawdzić przed wywołaniem metody używającej tego uchwytu. Można przesłać informację o błędzie do szerszego kontekstu przez stworzenie obiektu reprezentującego wiadomość i "wyrzucenie" go na zewnątrz aktualnego kontekstu. Nazywa się to zgłoszeniem (wyrzuceniem) wyjątku (ang. throwing), wygląda natomiast następująco: if(t==null) throw new NullPointerException(); Zostanie zgłoszony wyjątek, co w aktualnym kontekście zwalnia nas od odpowiedzialności.

65 Wykład Java ver Parametry wyjątków Jak każdy obiekt Javy, wyjątek tworzony jest na stercie przez instrukcję new, która przydziela pamięć i wywołuje konstruktor. We wszystkich standardowych wyjątkach istnieją dwa konstruktory: pierwszy jest konstruktorem domyślnym, a drugi przyjmuje łańcuch jako parametr tak, że można w wyjątku umieścić własny komentarz: if(t==null) throw new NullPointerException( t=null ); jak zobaczymy dalej, można później wydobyć ten łańcuch na wiele sposobów. słowo kluczowe throw powoduje kilka względnie "magicznych" rzeczy. Normalnie najpierw używamy new, aby stworzyć obiekt, który reprezentuje warunki zaistnienia błędu. Otrzymany uchwyt obiektu należy przekazać do throw. W rezultacie obiekt jest "zwracany" przez metodę nawet wtedy, gdy typ tego obiektu nie jest taki sam, jak zadeklarowany typ zwracany z metody. W uproszczeniu można obsługę wyjątków traktować jako alternatywną metodę zwracania wartości ~ bloku. Chociaż zbyt dosłowne traktowanie tej analogii prowadzi do kłopotów. Również ze zwykłego bloku można wyjść, zgłaszając wyjątek - wtedy zostanie zwrócona domyślna wartość metoda lub blok będzie opuszczony. Blok try Jeśli wyrzucimy wyjątek, znajdując się wewnątrz metody (albo jedna z wywoływanych wewnątrz metod wyrzuci wyjątek), to wykonanie metody zostanie przerwane przez proces zwracania wyjątku. Jeśli nie chcemy, aby throw powodowało wyjście z metody, to należy w tej metodzie wstawić specjalny blok przechwytujący wyjątki. Nazywa się on blokiem prób (ang. try), ponieważ wewnątrz niego "próbujemy" wywołać różne metody. Blok prób jest normalnym blokiem poprzedzonym słowem kluczowym try: try { // Kod który może spowodować wyjątek Obsługa błędów w językach programowania nie posiadających mechanizmu obsługi wyjątków wymagała otoczenia każdego wywołania metody kodem ustawiającym i testującym kody błędów, nawet jeśli ta sama metoda była wywoływana kilkakrotnie. Z obsługą wyjątków można wstawić wszystko w blok try i przechwytywać wszystkie wyjątki w jednym miejscu. Oznacza to, że kod jest łatwiej pisać i łatwiej czytać, ponieważ jego przeznaczenie nie jest przesłonięte przez obsługę błędów. Obsługa wyjątków Oczywiście każdy wyrzucony wyjątek musi się gdzieś znaleźć. Tym "miejscem" jest procedura obsługi wyjątku i dla każdego typu wyjątków, który chcemy obsłużyć, musi istnieć osobna procedura. Procedury obsługi wyjątków następują bezpośrednio po bloku try i są oznaczone przez słowo kluczowe catch: try { // Kod który może spowodować wyjątek catch{typel idl) { // Obsłuż wyjątek typu Typel catch(type2 id2) { // Obsłuż wyjątek typu Type2 catch(type3 id3) {

66 Wykład Java ver // Obsłuż wyjątek typu Type3 [finally { // domyślna obsługa wyjątku- czynności, które są obsługiwane za każdym razem ] // itd... Każdy człon catch (procedura obsługi wyjątku) działa jak mała metoda, która pobiera tylko jeden parametr konkretnego typu. Identyfikatory (id1, id2 itd.) mogą być używane wewnątrz procedury tak samo jak parametry metody. Czasami nigdy nie używa się identyfikatorów, ponieważ sam typ wyjątku dostarcza wystarczającą ilość informacji, aby poradzić sobie z wyjątkiem. Mimo to zawsze trzeba deklarować identyfikator. Procedury obsługi muszą następować bezpośrednio po bloku try. Jeśli zostanie wyrzucony wyjątek, to mechanizm obsługi wyjątków rozpoczyna poszukiwanie pierwszej procedury, której parametr odpowiada typowi wyrzuconego wyjątku. Po wejściu w sekcję catch wyjątek uważa się za obsłużony. Poszukiwanie procedur zostaje zatrzymane po wyjściu z sekcji catch. Wykonywany jest tylko kod pasującej sekcji catch, a nie jak w instrukcji switch, która potrzebuje break na końcu każdego przypadku case, aby zapobiec wykonywaniu kolejnych przypadków. Zauważ, iż wewnątrz bloku try dowolna liczba różnych wywoływanych metod może generować ten sam wyjątek, ale wystarczy dla nich tylko jedna procedura obsługi. Kończenie czy wznawianie W teorii obsługi wyjątków wyróżnia się dwa modele. Przy kończeniu (tak wyjątki obsługuje Java i C++) zakłada się, że błąd jest tak krytyczny, że nie ma możliwości powrotu do miejsca, w którym pojawił się wyjątek. Ktokolwiek wyrzucił wyjątek, zdecydował, że nie ma sposobu, aby uratować sytuację i nie życzy sobie, aby wracać do tego miejsca. Alternatywne rozwiązanie nazywa się wznawianiem. Oznacza to, że spodziewamy się, iż procedu ra obsługi wyjątku zrobi coś, by naprawić system, a następnie można próbować wywołać wadliwą metodę, zakładając powodzenie drugiej próby. Jeśli chcemy wznowienia, to ciągle mamy nadzieję na kontynuację wykonania po obsłużeniu wyjątku. W tym wypadku wyjątek przypomina raczej wywołanie metody - i tak właśnie należy radzić sobie w Javie w sytuacjach, kiedy konieczne jest zachowanie w stylu wznawiania (czyli nie wyrzucamy wyjątku - wywołujemy metodę, która naprawi problem). Alternatywnie można umieścić blok try wewnątrz pętli while, która będzie powtarzała blok try aż do uzyskania żądanego rezultatu. W przeszłości programiści używający systemów operacyjnych, które obsługiwały wznawianą obsługę wyjątków, ostatecznie wybierali kod podobny do przerywającego, pomijając wznawianie. Zatem mimo iż na początku wznawianie może się wydawać atrakcyjne, to w praktyce nie jest zbyt użyteczne. Podstawowym powodem jest najprawdopodobniej powstającą wtedy zależność fragmentów kodu od siebie - procedura obsługi musi wiedzieć, skąd wyrzucono wyjątek, i zawierać odpowiedni kod, specyficzny dla każdego takiego miejsca. Powoduje to, że taki kod trudno jest tworzyć i utrzymywać, szczególnie w przypadku dużych systemów, gdzie wyjątek może być generowany w wielu miejscach. Typy Wyjątków Na szczycie hierarchii klas reprezentujących wyjątki znajduje się klasa Throwable. Każda klasa o nazwie występującej w podanym wyżej schemacie w nawiasach umieszczonych za słowem catch jest właśnie jedną z podklas klasy Throwable. Ma ona dwie bezpośrednie

67 Wykład Java ver podklasy, Exception i Error, dzielące wszystkie dalsze podklasy na dwie oddzielne grupy. Klasy Exception używa się z wyjątkami przechwytywanymi i generowanymi przez program. Natomiast klasa Error pozwala określać wyjątki, które w normalnej sytuacji nie powinny być przechwytywane. Podczas przechwytywania podklas klasy Error należy być bardzo ostrożnym, ponieważ zwykle oznaczają one wystąpienie bardzo poważnego błędu. Jeszcze bardziej specjalistyczny charakter ma podklasa klasy Exception o nazwie RuntimeException, reprezentująca wyjątki, których wystąpienie zostało spowodowane przez system czasu przebiegu Javy. Są one zwykle generowane automatycznie w następstwie nieprawidłowego działania programu. Obiekty reprezentujące wyjątki są tworzone automatycznie przez system czasu przebiegu w następstwie wystąpienia każdej sytuacji nietypowej. Na przykład zamieszczony niżej program przykładowy zawiera wyrażenie, które powoduje wygenerowanie wyjątku oznaczającego próbę dzielenia przez zero. plik: Dzielenie.java class Dzielenie { public static void main(string args[]) { int d=0; int a=42 /d; System.out.println("a/d="+a); Podczas próby wykonania tego działania system czasu przebiegu Javy, stwierdza, że dzielna jest równa zeru, w związku z czym tworzy obiekt wyjątku w celu przerwania wykonywania aktualnej instrukcji i umożliwienia programowi obsługi zaistniałego błędu. Mówimy wówczas, że system czasu przebiegu generuje (ang. throws) wyjątek. Przerwanie normalnego toku wykonywania programu w miejscu, w którym występuje instrukcja dzielenia, wiąże się z przejrzeniem aktualnego stosu wywołań (zawierającego adresy wywoływanych metod, ang. cali stack) w celu odnalezienia procedury obsługi wygenerowanego wyjątku. Przez procedurę obsługi wyjątku (ang. exception handler) rozumiemy sekwencję instrukcji wykonującą działania mające przeciwdziałać zaistniałej sytuacji nietypowej. W podanym przykładzie procedura taka nie została zdefiniowana, w związku z czym wykonana zostaje

68 Wykład Java ver procedura domyślna, należąca do systemu czasu przebiegu. Procedura ta wyświetla łańcuch (wartość obiektu typu String) zapisany w utworzonym obiekcie oraz zawartość stosu wywołań, opisującą miejsce, w którym pojawił się wyjątek. Komunikat wyświetlany przez podany wyżej przykład wygląda następująco: Zwróć uwagę na sposób wyświetlenia nazwy klasy Dzielenie(), nazwy metody main(), nazwy pliku Dzielenie.java oraz numeru wiersza zawierającego błędną instrukcję. Zauważ także, że typem utworzonego obiektu nie jest klasa Exception, czy tym bardziej Throwable, lecz specjalna podklasa klasy Exception, o nazwie ArithmeticException, dokładniej opisująca rodzaj zaistniałego błędu. Wprawdzie dokładne wyświetlanie zawartości stosu wywołań przez system przebiegu Javy po pojawieniu się wyjątku jest bardzo wygodne, ale często bardziej pożądane jest jego przechwycenie i obsłużenie przez program, a następnie kontynuowanie wykonywania programu. Za pomocą słowa kluczowego try można określić sekwencję instrukcji, w której mogą pojawić się przechwytywane przez program wyjątki. Bezpośrednio za blokiem try umieszcza się jeden lub więcej bloków catch, określających typy wyjątków, które mają być przechwytywane. Przedstawiony niżej program jest odpowiednikiem poprzedniego przykładu, z tym że zawiera konstrukcję try-catch.

69 Wykład Java ver plik: Dzielenie class Dzielenie { public static void main(string args[]) { try { int d=0; int a=42 /d; System.out.println("a/d="+a); catch(arithmeticexception e) { System.out.println("Dzielenie przez zero");

70 Wykład Java ver pliki:dziel.java class Dziel {public static void main(string args[]) { try { int a=args.length; System.out.println("a="+a); int b=42 /a; int c[]={ 1 ; c[42]=99; catch(arithmeticexception e) { System.out.println("Dzielenie przez zero"+e); catch(arrayindexoutofboundsexception e) { System.out.println("Przekroczenie zakresu tablicy"+e); catch(throwable t) { System.out.println("Otrzymano t:"+t); finally{system.out.println("koniec programu!!!");

71 Wykład Java ver Zakres bloku catch jest ograniczony do instrukcji znajdującej się bezpośrednio za słowem kluczowym try. Najczęściej jest to instrukcja złożona, składająca się z większej liczby instrukcji prostych; jeżeli ta część instrukcji try zawiera tylko jedną instrukcję prostą, to nie trzeba jej umieszczać w nawiasach klamrowych, ale pozostawienie ich nie jest błędem. Celem większości dobrze skonstruowanych bloków catch powinno być rozwiązanie zaistniałego problemu przez właściwe ustawienie odpowiednich zmiennych w celu umożliwienia dalszego działania programu, tak jakby błąd nie wystąpił. Jeżeli obsługą wyjątku nie zajął się wywołany podprogram, to zadanie to przejmuje metoda znajdująca się na stosie wywołań bezpośrednio nad nim. Jeśli i ta metoda nie obsługuje wyjątku, to otrzymuje go następna, aż do osiągnięcia maksymalnego poziomu, zajmowanego przez domyślną procedurę obsługi wyjątków, należącą do systemu czasu przebiegu Javy. Po wygenerowaniu wyjątku instrukcje aktualnej metody przestają być nagle wykonywane liniowo - część instrukcji jest chwilowo pomijana, a w przypadku braku odpowiedniego bloku catch dochodzi nawet do zakończenia działania programu. Czasami jednak chcemy mieć pewność, że określony fragment danego programu będzie zawsze wykonywany, niezależnie od tego, które wyjątki zostały wygenerowane czy przechwycone. Fragment taki można wskazać za pomocą słowa kluczowego finally. Nawet jeśli nie istnieje blok catch odpowiadający typowi wygenerowanego wyjątku, blok finally jest wykonywany przed przekazaniem sterowania pierwszej instrukcji znajdującej się za konstrukcją try. W każdej konstrukcji try musi znajdować się co najmniej jeden blok catch lub finally. Blok finally jest wykonywany tuż przed powrotem do metody wywołującej, spowodowanym brakiem odpowiedniego bloku catch lub wystąpieniem instrukcji return. Jest to wygodny sposób zamykania plików i zwalniania wszystkich innych zasobów, które zostały przydzielone aktualnej metodzie na początku jej wykonywania. Blok finally jest opcjonalny i w prostych konstrukcjach try-catch, nie wymagających gwarancji wykonania jakichkolwiek instrukcji, można go pominąć. Instrukcje try zagnieżdża się w podobny sposób Jak zakresy zmiennych. Na przykład w pewnym bloku try można umieścić wywołanie metody zawierającej kolejną konstrukcję try, związaną z inną sekwencją instrukcji. Kontekst każdej instrukcji try jest pamiętany od rozpoczęcia do zakończenia jej wykonywania. Jeżeli instrukcja try najniższego poziomu nie zawiera bloku catch odpowiadającego typowi wygenerowanego wyjątku, to jest on przekazywany do metody wyższego poziomu. W przypadku, gdy w żadnej z metod programu

72 Wykład Java ver nie ma bloku catch, który by obsługiwał wyjątki danego typu, wykonywana jest domyślna procedura systemu czasu przebiegu. Instrukcji throw używa się do ponownego, "ręcznego" generowania wyjątków. W tym celu należy najpierw uzyskać uchwyt egzemplarza klasy Throwable, odczytując wartość parametru pobieranego przez blok catch lub korzystając z operatora new Ogólna postać instrukcji throw wygląda następująco: throw EgzemplarzKlasyThrowable Natychmiast po napotkaniu instrukcji throw normalny tok wykonywania programu, ulega przerwaniu i zamiast następnej instrukcji wykonywany jest blok catch obsługujący wyjątki o typie określonym za słowem throw i związany z wykonywanym blokiem try. Jeżeli blok taki nie istnieje w aktualnie wykonywanej konstrukcji try, to jest on szukany w konstrukcjach nadrzędnych. W przypadku, gdy odpowiedni blok catch nie istnieje. w całym programie, wywoływana jest domyślna procedura obsługi wyjątków (należąca do systemu czasu przebiegu), która wyświetla odpowiedni komunikat i przerywa wykonywanie programu. Podany niżej program przykładowy zawiera metodę generującą dwukrotnie ten sam wyjątek. Za drugim razem jest on przekazywany metodzie wyższego poziomu: plik:insthrow class insthrow {static void ruszaj() {try{throw new NullPointerException("wyswietl ruszaj"); catch(nullpointerexception e) {System.out.println("Przechwycony w metodzie ruszaj()"); throw e; public static void main(string args[]) {try {ruszaj(); catch(nullpointerexception t) {System.out.println("Ponownie przechwycony:" +t);

73 Wykład Java ver Jeżeli metoda jest zdolna generować wyjątek, którego sama nie przechwytuje, należy to zaznaczyć w tekście programu, aby metody ją wywołujące mogły się przed nim zabezpieczyć. Listę wszystkich wyjątków generowanych przez daną metodę tworzy się za pomocą słowa kluczowego throws. Kompilator wymaga deklarowania wyjątków reprezentowanych przez klasę Exception oraz większość jej podklas Stwierdzenie to nie dotyczy klas Error i RuntimeException oraz ich wszystkich podklas, ponieważ zakłada się, że podczas normalnego wykonywania programu nie powinny się one pojawić. Tak więc za pomocą słowa kluczowego throws należy podać nazwy wszystkich wyjątków, które są generowane "ręcznie" przez daną metodę i są reprezentowane przez klasę Exception lub jedną z jej podklas, z wyłączeniem podklasy RuntimeException. W związku z tym pełna postać deklaracji metody wygląda następująco: typ nazwa_metody (lista_parametrów) throws lista_wyjątków { Podany niżej program zawiera metodę, która usiłuje wygenerować wyjątek, mimo iż sama go nie obsługuje i nie deklaruje jego nazwy za pomocą słowa kluczowego throws. Próba skompilowania tego programu kończy się wyświetleniem komunikatu o błędzie. I plik:insthrow1 class insthrow1 {static void ruszaj() throws IllegalAccessException {System.out.println("W metodzie ruszaj()"); throw new IllegalAccessException("do wgl\u0104du"); public static void main(string args[]) {try {ruszaj(); catch(illegalaccessexception l) {System.out.println("Ponownie przechwycony:" +l);

74 Wykład Java ver Wygenerowane i przechwycone mogą być wyłącznie wyjątki reprezentowane przez podklasy klasy Throwable. W charakterze wyjątków nie można używać typów prostych, takich jak int czy char, ani innych obiektów, w rodzaju String czy Object. Najczęściej do reprezentowania wyjątków używa się samodzielnie utworzonych klas będących podklasami klasy Exception. Implementacja takich klas jest bardzo prosta, a mimo to ich istnienie pozwala tworzyć programy z czytelną obsługą błędów oraz jasnymi, zorientowanymi obiektowo interfejsami przeznaczonymi dla użytkowników definiowanych klas. Interfejsy takie zawierają nie tylko definicje metod publicznych, ale także typy generowanych wyjątków. Podany niżej program przykładowy deklaruje nową podklasę klasy Exception, której następnie używa do zasygnalizowania błędu. plik: blad class blad extends Exception {private int dane; blad(int a) {dane=a; public String tostring() {return "Blad["+dane+"]"; plik:insthrow2 class insthrow2{ static void ruszaj(int a) throws blad {System.out.println("W metodzie ruszaj("+a+")"); if(a>10) throw new blad(a); System.out.println("Koniec ruszaj()"); public static void main(string args[]) {try {ruszaj(1); ruszaj(20); catch(blad l){system.out.println(" przechwycony przez wyj\u0104tek blad:" +l);

75 Wykład Java ver Zakończenie Obsługa wyjątków - to niezwykle wszechstronny. i pożyteczny mechanizm sterowania skomplikowanymi programami, których działanie może przebiegać na wiele różnych sposobów. Jednak słowa kluczowe try, throw i catch należy traktować wyłącznie jako elementy czytelnej obsługi błędów i nietypowych sytuacji pojawiających się podczas wykonywania programu. Niewłaściwe byłoby używanie ich w celu przechodzenia do innych metod, czyli w charakterze mechanizmu przypominającego istniejącą w innych językach instrukcję goto. Wyjątki systemowe Javy. Wszystkie wyjątki Javy dziedziczą po klasie Exception. Jest wiele możliwych wyjątków. Tutaj są przedstawione tylko najczęściej stosowane. ArithmeticException - Ten wyjątek napotkasz, gdy będziesz próbował wykonać niedozwoloną operację arytmetyczną, na przykład dzielenie przez zero. (Pamiętaj, że liczby zmiennopozycyjne nie zgłaszają wyjątków). ArrayIndexOutOfBoundsException - Java zgłosi ten wyjątek, gdy spróbujesz sięgnąć do elementu poza zakresem tablicy. ClassCastException - Ten wyjątek da o sobie znać, gdy spróbujesz rzutować obiekt do typu nie będącego na tej samej gałęzi hierarchii klas. (Na przykład, gdy spróbujesz rzutować Integer na String). InterruptedException - Ten wyjątek otrzymasz, gdy jeden wątek niespodziewanie przerwie pracę drugiego. IOException-Ten wyjątek oznacza, że stało się coś z wejściem- -wyjściem, na przykład nastąpiła próba czytania za końcem pliku. NullPointerException - Uzyskasz ten wyjątek wtedy, kiedy niepoprawnie użyjesz wskaźnika null. Jednym z częstszych sposobów uzyskania go jest sytuacja, gdy przy wywołaniu dwu metod jedna za drugą pierwsza z nich zwróci null zamiast obiektu, na przykład: firstmethod ().secondmethod (). OutOfMemoryException - Ten wyjątek otrzymasz, gdy zabraknie Ci pamięci operacyjnej.

76 Wykład Java ver Wątki i ich synchronizacja Programowanie wielowątkowe (ang. multi-threaded programming) charakteryzuje się tym, że tworzone programy dzieli się na dwa lub więcej procesów, które mogą przebiegać równocześnie. Okazuje się, że najlepiej jest, jeśli wiele zadań występujących w interakcyjnych programach jest wykonywanych współbieżnie. Do zadań takich należy między innymi: odczytywanie i zapisywanie plików, korzystanie z zasobów sieciowych, reagowanie na dane wprowadzane przez użytkownika, wykonywanie skomplikowanych, trwających nieraz kilka sekund obliczeń, a także wyświetlanie animacji i interfejsu użytkownika. Wszystkie te działania muszą programy wykonywać w taki sposób, aby użytkownik nie musiał czekać zbyt długo na ich zakończenie. Interesującą właściwością wszystkich wymienionych procesów przebiegających równolegle jest to, że większość z nich nie potrzebuje przez cały czas wszystkich zasobów komputera. Na przykład czas procesora niezbędny do transmisji danych jest minimalny, mimo iż wczytywanie strumienia danych z wolnej sieci może trwać minutę lub nawet dłużej. Również i reagowanie na dane wprowadzane przez użytkownika, na przykład za pomocą klawiatury, nie wymaga dużej aktywności ze strony jednostki centralnej - nawet najszybsza maszynistka nie jest w stanie nacisnąć w ciągu sekundy więcej niż dziesięć klawiszy. Rysunki tworzące animacje są zwykle wyświetlane od pięciu do dziesięciu razy na sekundę, więc również i podczas wykonywania tej czynności procesor przez większość czasu jest bezczynny. Nawet skomplikowane obliczenia nie muszą zajmować l00% czasu procesora, jeśli założyć, że ich wynik nie jest natychmiast potrzebny. Problem występujący w tradycyjnych jednowątkowych środowiskach polega na tym, że przed przystąpieniem do wykonywania następnego procesu trzeba poczekać na zakończenie poprzedniego. Nawet jeśli przez większość czasu procesor pozostaje bezczynny, to kolejne zadania muszą czekać na swoją kolej. W systemach jednowątkowych stosowane. jest rozwiązanie zwane pętlą zdarzeń z odpytywaniem (ang. event loop with polling). W takim modelu istnieje jedna pętla nieskończona, w której wykonywane są kolejne wątki pobierane z kolejki procesów. Poszczególne wątki, takie jak odczytanie pliku sieciowego czy wyświetlenie kolejnej klatki animacji, są wykonywane przez odpowiadające im procedury obsługi zdarzeń. Do zakończenia bieżącego wątku, czyli do czasu powrotu z odpowiedniej procedury, nie może być podjęte w systemie żadne inne działanie. W systemie wielowątkowym wykorzystuje się fakt, że większość czasu wykonywania wątków traci się na czekanie, aż potrzebny zasób stanie się dostępny. Jeżeli wszystkie procesy

77 Wykład Java ver są niezależnymi wątkami, a system potrafi przełączać się między wątkiem oczekującym aktualnie na jakiś zasób, a innym, gotowym do działania, to w tym samym czasie można wykonać znacznie więcej działań. Wystąpienie sytuacji, w której więcej wątków potrzebuje jednocześnie dużo czasu procesora, jest bardzo mało prawdopodobne. Ponieważ większość systemów operacyjnych nie ma dobrych mechanizmów przetwarzania wielowątkowego, to tradycyjne języki programowania, takie jak C++, nie zawierają elementów umożliwiających łatwe i czytelne opisywanie wątków. Poszczególne części programów są w tym przypadku synchronizowane za pomocą pojedynczej pętli zdarzeń. Innymi słowy, środowiska tradycyjne, do których zaliczają się między innymi Apple Macintosh, Microsoft Windows oraz X11/Motif, są synchronicznymi systemami zarządzanymi zdarzeniami. Java była projektowana od początku w warunkach. zarządzania wątkami na poziomie systemu operacyjnego. Z wątków korzysta w dużym stopniu system czasu przebiegu Javy, również wszystkie biblioteki klas były projektowane z myślą o przetwarzaniu wielowątkowym. Opóźnienia w utworzeniu systemów Javy dla Macintosha i MS-DOS-a wynikały właśnie z faktu, że żaden z tych systemów nie zawiera dobrych mechanizmów do zarządzania wątkami. Uwzględnienie wątków spowodowało, że środowisko programowania Javy stało się asynchroniczne. W programach Javy nie ma już pojedynczej pętli zdarzeń. Na przykład w czasie, gdy jeden wątek odczytuje dane z sieci, wszystkie pozostałe mogą działać bez jakichkolwiek przerw. Problemu nie stwarza również wątek czekający na dane wprowadzane przez użytkownika za pomocą klawiatury lub myszy czy wątek wyświetlający animację i nie wykonujący żadnych działań między wyświetlaniem kolejnych klatek. UWAGA: Jeżeli wykonywanie jakiegoś wątku zostało zablokowane, gdyż na przykład czeka on na wprowadzenie danych przez użytkownika, to wszystkie pozostałe wątki działają w sposób niezakłócony. Inaczej wygląda sytuacja w środowisku jednowątkowym, gdzie pojedynczy proces może zahamować działanie całego programu. Po uruchomieniu wątku można go zawiesić, czyli tymczasowo przerwać jego wykonywanie, a następnie wznowić. Wznowiony wątek kontynuuje działanie od miejsca, w którym został zawieszony. Istnieje również możliwość zatrzymania wątku, czyli natychmiastowego zakończenia jego wykonywania. Zatrzymanego wątku nie można ponownie wznowić. System czasu przebiegu Javy używa priorytetów w celu określenia wzajemnej zależności między wykonywaniem poszczególnych wątków. Priorytety wątków są liczbami całkowitymi z zakresu od 1 do 10 określającymi ważność jednego wątku względem drugiego. Mają one

78 Wykład Java ver znaczenie tylko wtedy, gdy są rozpatrywane łącznie. Jeśli w danej chwili istnieje w systemie tylko jeden wątek, to szybkość jego wykonywania nie zależy w najmniejszym stopniu od jego priorytetu -procesor może i tak wykonywać jednocześnie tylko jedną instrukcję. Priorytety stają się istotne dopiero wtedy, gdy więcej wątków ubiega się o przydział procesora. Przerwanie wykonywania jednego wątku i przydzielenie czasu procesora innemu nazywa się przełączaniem kontekstu (ang. context-switch). Zasady wykonywania tego zadania są proste, Każdy wątek może sam zwolnić procesor lub może zostać wywłaszczony. (ang. pre-empted). W pierwszym przypadku sterowanie przejmuje wątek o najwyższym priorytecie spośród wszystkich gotowych do działania. Druga sytuacja polega na tym, że wątek, który nie zwalnia procesora "dobrowolnie", jest go i tak pozbawiany, niezależnie od rodzaju wykonywanego zadania - następuje to wtedy, gdy pojawia się wątek o wyższym priorytecie. W zasadzie, wątek o wyższym priorytecie, który zgłasza gotowość do działania, otrzymuje natychmiast czas procesora. Takie rozwiązanie nazywa się wielozadaniowością z wywłaszczaniem (ang. pre-emptive multi-tasking). Jeżeli o czas procesora ubiegają się dwa wątki o takim samym priorytecie, to każdy z nim musi sam oddać sterowanie drugiemu. OSTRZEŻENIE: Niestety, w specyfikacji systemu czasu przebiegu Javy istnieje dwuznaczność. System działający w środowisku Windows 95 przydziela cyklicznie czas procesora kolejnym wątkom o takim samym priorytecie, podczas gdy system czasu przebiegu środowiska Solaris 2.x pozwala jednemu wątkowi całkowicie zablokować wykonywanie innych. Ponieważ istnienie wielu wątków powoduje asynchroniczne wykonywanie programów, programista musi mieć możliwość ich zsynchronizowania. Na przykład, jeśli dwa wątki mają współdzielić skomplikowaną strukturę danych, taką jak lista wiązana, to nie można dopuścić do tego, by wystąpiła między nimi kolizja. Dlatego w Javie został zaimplementowany znany od dawna model synchronizacji wewnątrzprocesowej, zwany monitorem. W modelu tym monitor można sobie wyobrazić jako bardzo małą skrzynkę, w której może się pomieścić tylko jeden wątek. W chwili, gdy do monitora dostaje się pewien wątek, wszystkie pozostałe muszą czekać, aż urządzenie to zostanie zwolnione. Tego rodzaju monitory można wykorzystywać do ochrony współdzielonych zasobów przed ich jednoczesnym wykorzystywaniem przez większą liczbę wątków. W większości systemów wielowątkowych funkcje monitorów pełnią obiekty. W Javie stosowane jest inne rozwiązanie. Nie ma tu klasy o nazwie Monitor, a zamiast tego każdy obiekt ma swój własny monitor, do którego każdy wątek może wejść przez wywołanie jednej z metod oznaczonych słowem kluczowym synchronized. W czasie, gdy jeden z wątków wykonuje metodę synchronizowaną, żaden inny nie może wywołać jakiejkolwiek innej metody synchronizowanej tego samego obiektu.

79 Wykład Java ver Podobnie jak wszystkie inne pojęcia Javy, wątki są reprezentowane przez obiekty określonej klasy. Nosi ona nazwę Thread i zawiera wszystkie metody niezbędne do zarządzania wątkami. Ważne jest, aby odróżniać wykonywany wątek od reprezentującego go obiektu klasy Thread, mimo iż występująca między nimi różnica jest subtelna. Obiekt typu Thread należy traktować jako panel sterowania wątku, zawierający metody, które umożliwiają jego uruchomienie, "uśpienie", zawieszenie i zatrzymanie. Klasa Thread jest jedynym elementem Javy pozwalającym na zarządzanie wątkami. Każdy wątek w pewnym momencie zaczyna się, następnie wykonuje określoną liczbę działań, po czym kończy się. Wszystkie programy przykładowe, które omawialiśmy do tej pory, składały się tylko z jednego wątku - od początku do końca ich działania był wykonywany tylko jeden wątek. W momencie uruchomienia każdego programu Javy jeden wątek już działa. O tym, który wątek jest w danej chwili wykonywany, można dowiedzieć się za pomocą metody statycznej Thread.currentThreadO. Po uzyskaniu uchwytu do bieżącego wątku pojawia się możliwość wykonania kilku interesujących działań. Ponieważ korzystanie z jednego tylko wątku nie jest zbyt interesujące, musimy odpowiedzieć na pytanie, w jaki sposób tworzy się kolejne wątki. Ogólnie mówiąc, polega to na tworzeniu kolejnych egzemplarzy klasy Thread. Nowo tworzony obiekt trzeba powiadomić o tym, który fragment programu ma być wykonywany w ramach nowego wątku. Może to być dowolny obiekt implementujący interfejs Runnable. Interfejs Runnable jest prostym interfejsem reprezentującym dowolny fragment programu działający asynchronicznie. Aby go zaimplementować, wystarczy zdefiniować tylko jedną metodę, o nazwie run(). Przykład utworzenia nowego wątku został podany niżej.

80 Wykład Java ver class wielo implements Runnable { wielo(int f) {Thread ct=thread.currentthread(); ct.setname("wątek pierwszy"); System.out.println("Utworzony wątek pierwszy: "+ct+f); Thread t= new Thread(this,"Wątek drugi"); System.out.println("Utworzony wątek drugi: "+t+f); t.start(); try{thread.sleep(3000); catch(interruptedexception e) {System.out.println("Przerwanie wątku głównego: "+e); System.out.println("wątek pierwszy stop: "+f); public void run() {try{ for(int n=5;n>=0;n--) {System.out.println("n="+n); Thread.sleep(1000); catch(interruptedexception e) {System.out.println("Przerwanie wątku potomnego"); System.out.println("wątek potomny stop"); public static void main(string args[]) {wielo zm=new wielo(4); wielo zm1=new wielo(8); Liczba 5 jest wartością domyślną priorytetu wątku Wątek pierwszy, została włą czona do reprezentacji łań cuchowej obiektu typu Thread. main to nazwa grupy do której on należy

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce. 1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,

Bardziej szczegółowo

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02 METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE Wykład 02 NAJPROSTSZY PROGRAM /* (Prawie) najprostszy przykład programu w C */ /*==================*/ /* Między tymi znaczkami można pisać, co się

Bardziej szczegółowo

Typy danych, zmienne i tablice. Tomasz Borzyszkowski

Typy danych, zmienne i tablice. Tomasz Borzyszkowski Typy danych, zmienne i tablice Tomasz Borzyszkowski Silne typy Javy Java jest językiem wyposażonym w silny system typów. Wywodzi się stąd siła i bezpieczeństwo tego języka. Co to znaczy silny system typów?

Bardziej szczegółowo

JAVA. Platforma JSE: Środowiska programistyczne dla języka Java. Wstęp do programowania w języku obiektowym. Opracował: Andrzej Nowak

JAVA. Platforma JSE: Środowiska programistyczne dla języka Java. Wstęp do programowania w języku obiektowym. Opracował: Andrzej Nowak JAVA Wstęp do programowania w języku obiektowym Bibliografia: JAVA Szkoła programowania, D. Trajkowska Ćwiczenia praktyczne JAVA. Wydanie III,M. Lis Platforma JSE: Opracował: Andrzej Nowak JSE (Java Standard

Bardziej szczegółowo

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce. 1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,

Bardziej szczegółowo

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta 16.09.2006. Strona 1 z 26. Powrót. Full Screen. Zamknij.

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta 16.09.2006. Strona 1 z 26. Powrót. Full Screen. Zamknij. Programowanie Sobera Jolanta 16.09.2006 Strona 1 z 26 1 Wprowadzenie do programowania 4 2 Pierwsza aplikacja 5 3 Typy danych 6 4 Operatory 9 Strona 2 z 26 5 Instrukcje sterujące 12 6 Podprogramy 15 7 Tablice

Bardziej szczegółowo

Czym jest Java? Rozumiana jako środowisko do uruchamiania programów Platforma software owa

Czym jest Java? Rozumiana jako środowisko do uruchamiania programów Platforma software owa 1 Java Wprowadzenie 2 Czym jest Java? Język programowania prosty zorientowany obiektowo rozproszony interpretowany wydajny Platforma bezpieczny wielowątkowy przenaszalny dynamiczny Rozumiana jako środowisko

Bardziej szczegółowo

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Program, to lista poleceń zapisana w jednym języku programowania zgodnie z obowiązującymi w nim zasadami. Celem programu jest przetwarzanie

Bardziej szczegółowo

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji. JAVA Java jest wszechstronnym językiem programowania, zorientowanym obiektowo, dostarczającym możliwość uruchamiania apletów oraz samodzielnych aplikacji. Java nie jest typowym kompilatorem. Źródłowy kod

Bardziej szczegółowo

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak Java język programowania obiektowego Programowanie w językach wysokiego poziomu mgr inż. Anna Wawszczak 1 Język Java Język Java powstał w roku 1995 w firmie SUN Microsystems Java jest językiem: wysokiego

Bardziej szczegółowo

Multimedia JAVA. Historia

Multimedia JAVA. Historia Multimedia JAVA mgr inż. Piotr Odya piotrod@sound.eti.pg.gda.pl Historia 1990 rozpoczęcie prac nad nowym systemem operacyjnym w firmie SUN, do jego tworzenia postanowiono wykorzystać nowy język programowania

Bardziej szczegółowo

2 Przygotował: mgr inż. Maciej Lasota

2 Przygotował: mgr inż. Maciej Lasota Laboratorium nr 2 1/7 Język C Instrukcja laboratoryjna Temat: Wprowadzenie do języka C 2 Przygotował: mgr inż. Maciej Lasota 1) Wprowadzenie do języka C. Język C jest językiem programowania ogólnego zastosowania

Bardziej szczegółowo

Java jako język programowania

Java jako język programowania Java jako język programowania Interpretowany programy wykonują się na wirtualnej maszynie (JVM Java Virtual Machine) Składnia oparta o język C++ W pełni zorientowany obiektowo (wszystko jest obiektem)

Bardziej szczegółowo

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz Programowanie obiektowe Literatura: Autor: dr inŝ. Zofia Kruczkiewicz Java P. L. Lemay, Naughton R. Cadenhead Java Podręcznik 2 dla kaŝdego Języka Programowania Java Linki Krzysztof Boone oprogramowania

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Programowanie obiektowe Laboratorium 1. Wstęp do programowania w języku Java. Narzędzia 1. Aby móc tworzyć programy w języku Java, potrzebny jest zestaw narzędzi Java Development Kit, który można ściągnąć

Bardziej szczegółowo

Programowanie strukturalne i obiektowe

Programowanie strukturalne i obiektowe Programowanie strukturalne i obiektowe Język C część I Opracował: Grzegorz Flesik Literatura: A. Majczak, Programowanie strukturalne i obiektowe, Helion, Gliwice 2010 P. Domka, M. Łokińska, Programowanie

Bardziej szczegółowo

Programowanie w Internecie. Java

Programowanie w Internecie. Java Programowanie w Internecie Java Autor: dr inż. Zofia Kruczkiewicz Literatura: L. Lemay, R. Cadenhead P. Naughton Krzysztof Barteczko Boone Barry Java 2 dla każdego Podręcznik Języka Programowania Java

Bardziej szczegółowo

Informatyka, Ćwiczenie 1. 1. Uruchomienie Microsoft Visual C++ Politechnika Rzeszowska, Wojciech Szydełko. I. ZałoŜenie nowego projektu

Informatyka, Ćwiczenie 1. 1. Uruchomienie Microsoft Visual C++ Politechnika Rzeszowska, Wojciech Szydełko. I. ZałoŜenie nowego projektu Informatyka, Ćwiczenie 1 1. Uruchomienie Microsoft Visual C++ I. ZałoŜenie nowego projektu Wybieramy menu: File>New>Files jak na rys. poniŝej Zapisujemy projekt pod nazwą LAN, w katalogu d:\temp\lab typu

Bardziej szczegółowo

Powtórka algorytmów. Wprowadzenie do języka Java.

Powtórka algorytmów. Wprowadzenie do języka Java. Powtórka algorytmów. Wprowadzenie do języka Java. Przypomnienie schematów blokowych BEGIN Readln(a); Readln(b); Suma := 0; IF Suma < 10 THEN Writeln( Suma wynosi:, Suma); ELSE Writeln( Suma większa niż

Bardziej szczegółowo

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach? Część XVIII C++ Funkcje Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach? Umiemy już podzielić nasz

Bardziej szczegółowo

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut. Konstruktory Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut. Rozpatrzmy przykład przedstawiający klasę Prostokat: class

Bardziej szczegółowo

Język ludzki kod maszynowy

Język ludzki kod maszynowy Język ludzki kod maszynowy poziom wysoki Język ludzki (mowa) Język programowania wysokiego poziomu Jeśli liczba punktów jest większa niż 50, test zostaje zaliczony; w przeciwnym razie testu nie zalicza

Bardziej szczegółowo

Język JAVA podstawy. wykład 2, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Język JAVA podstawy. wykład 2, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna Język JAVA podstawy wykład 2, część 1 1 Język JAVA podstawy Plan wykładu: 1. Rodzaje programów w Javie 2. Tworzenie aplikacji 3. Tworzenie apletów 4. Obsługa archiwów 5. Wyjątki 6. Klasa w klasie! 2 Język

Bardziej szczegółowo

Rozdział 4 KLASY, OBIEKTY, METODY

Rozdział 4 KLASY, OBIEKTY, METODY Rozdział 4 KLASY, OBIEKTY, METODY Java jest językiem w pełni zorientowanym obiektowo. Wszystkie elementy opisujące dane, za wyjątkiem zmiennych prostych są obiektami. Sam program też jest obiektem pewnej

Bardziej szczegółowo

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość 1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość 2. Poprawna definicja wskażnika b to: a) float *a, **b = &a; b) float

Bardziej szczegółowo

WPROWADZENIE DO JĘZYKA JAVA

WPROWADZENIE DO JĘZYKA JAVA WPROWADZENIE DO JĘZYKA JAVA programowanie obiektowe KRÓTKA HISTORIA JĘZYKA JAVA KRÓTKA HISTORIA JĘZYKA JAVA 1991 - narodziny języka java. Pierwsza nazwa Oak (dąb). KRÓTKA HISTORIA JĘZYKA JAVA 1991 - narodziny

Bardziej szczegółowo

Microsoft IT Academy kurs programowania

Microsoft IT Academy kurs programowania Microsoft IT Academy kurs programowania Podstawy języka C# Maciej Hawryluk Język C# Język zarządzany (managed language) Kompilacja do języka pośredniego (Intermediate Language) Kompilacja do kodu maszynowego

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Programowanie obiektowe Literatura: Autor: dr inŝ. Zofia Kruczkiewicz Java P. L. Krzysztof Lemay, Naughton Barteczko R. Cadenhead JAVA, Java Podręcznik 2 wykłady dla kaŝdego Języka i ćwiczenia Programowania

Bardziej szczegółowo

Programowanie obiektowe zastosowanie języka Java SE

Programowanie obiektowe zastosowanie języka Java SE Programowanie obiektowe zastosowanie języka Java SE Wstęp do programowania obiektowego w Javie Autor: dr inŝ. 1 Java? Java język programowania obiektowo zorientowany wysokiego poziomu platforma Javy z

Bardziej szczegółowo

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main. Część XVI C++ Funkcje Jeśli nasz program rozrósł się już do kilkudziesięciu linijek, warto pomyśleć o jego podziale na mniejsze części. Poznajmy więc funkcje. Szybko się przekonamy, że funkcja to bardzo

Bardziej szczegółowo

Jak napisać program obliczający pola powierzchni różnych figur płaskich?

Jak napisać program obliczający pola powierzchni różnych figur płaskich? Część IX C++ Jak napisać program obliczający pola powierzchni różnych figur płaskich? Na początku, przed stworzeniem właściwego kodu programu zaprojektujemy naszą aplikację i stworzymy schemat blokowy

Bardziej szczegółowo

Java Język programowania

Java Język programowania Java Język programowania Język Java Bazuje i jest zbliżony do C/C++ Porosty zbiór typów danych (podział na typy prymitywne i obiektowe) Zarządzanie pamięcią i Garbage Collection Zintegrowana synchronizacja

Bardziej szczegółowo

Algorytm. a programowanie -

Algorytm. a programowanie - Algorytm a programowanie - Program komputerowy: Program komputerowy można rozumieć jako: kod źródłowy - program komputerowy zapisany w pewnym języku programowania, zestaw poszczególnych instrukcji, plik

Bardziej szczegółowo

Pascal typy danych. Typy pascalowe. Zmienna i typ. Podział typów danych:

Pascal typy danych. Typy pascalowe. Zmienna i typ. Podział typów danych: Zmienna i typ Pascal typy danych Zmienna to obiekt, który może przybierać różne wartości. Typ zmiennej to zakres wartości, które może przybierać zmienna. Deklarujemy je w nagłówku poprzedzając słowem kluczowym

Bardziej szczegółowo

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Java - tablice, konstruktory, dziedziczenie i hermetyzacja Java - tablice, konstruktory, dziedziczenie i hermetyzacja Programowanie w językach wysokiego poziomu mgr inż. Anna Wawszczak PLAN WYKŁADU zmienne tablicowe konstruktory klas dziedziczenie hermetyzacja

Bardziej szczegółowo

Spis treści. 1 Java T M

Spis treści. 1 Java T M Spis treści 1 Java T M 1 2 Co to jest Platforma Java T M 1 3 Przygotowanie komputera 2 4 Pierwszy program 2 5 Dokumentacja 3 6 Budowa aplikacji. Klasy. 3 7 Pola i metody 4 8 Konstruktory 5 9 Inne proste

Bardziej szczegółowo

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane Stałe Oprócz zmiennych w programie mamy też stałe, które jak sama nazwa mówi, zachowują swoją wartość przez cały czas działania programu. Można

Bardziej szczegółowo

Języki skryptowe w programie Plans

Języki skryptowe w programie Plans Języki skryptowe w programie Plans Warsztaty uŝytkowników programu PLANS Kościelisko 2010 Zalety skryptów Automatyzacja powtarzających się czynności Rozszerzenie moŝliwości programu Budowa własnych algorytmów

Bardziej szczegółowo

2. Składnia, środowisko i konwencje w Javie

2. Składnia, środowisko i konwencje w Javie Gdańsk, 2014 Ogólnie o Javie Środowisko Java jest językiem programowania, którego podstawowym celem jest realizacja zasady write once, run anywhere. Oznacza to możliwość wykonania tego samego programu,

Bardziej szczegółowo

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej Programowanie obiektowe Interfejsy Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej pawel.rogalinski pwr.wroc.pl Interfejsy Autor: Paweł Rogaliński Instytut Informatyki,

Bardziej szczegółowo

INFORMATYKA, TECHNOLOGIA INFORMACYJNA ORAZ INFORMATYKA W LOGISTYCE

INFORMATYKA, TECHNOLOGIA INFORMACYJNA ORAZ INFORMATYKA W LOGISTYCE Studia podyplomowe dla nauczycieli INFORMATYKA, TECHNOLOGIA INFORMACYJNA ORAZ INFORMATYKA W LOGISTYCE Przedmiot JĘZYKI PROGRAMOWANIA DEFINICJE I PODSTAWOWE POJĘCIA Autor mgr Sławomir Ciernicki 1/7 Aby

Bardziej szczegółowo

Języki programowania zasady ich tworzenia

Języki programowania zasady ich tworzenia Strona 1 z 18 Języki programowania zasady ich tworzenia Definicja 5 Językami formalnymi nazywamy każdy system, w którym stosując dobrze określone reguły należące do ustalonego zbioru, możemy uzyskać wszystkie

Bardziej szczegółowo

Wykład 4: Klasy i Metody

Wykład 4: Klasy i Metody Wykład 4: Klasy i Metody Klasa Podstawa języka. Każde pojęcie które chcemy opisać w języku musi być zawarte w definicji klasy. Klasa definiuje nowy typ danych, których wartościami są obiekty: klasa to

Bardziej szczegółowo

Podstawy programowania obiektowego

Podstawy programowania obiektowego Podstawy programowania obiektowego Technologie internetowe Wykład 5 Program wykładu Podejście obiektowe kontra strukturalne do tworzenie programu Pojęcie klasy i obiektu Składowe klasy: pola i metody Tworzenie

Bardziej szczegółowo

Kurs programowania. Wstęp - wykład 0. Wojciech Macyna. 22 lutego 2016

Kurs programowania. Wstęp - wykład 0. Wojciech Macyna. 22 lutego 2016 Wstęp - wykład 0 22 lutego 2016 Historia Simula 67 język zaprojektowany do zastosowan symulacyjnych; Smalltalk 80 pierwszy język w pełni obiektowy; Dodawanie obiektowości do języków imperatywnych: Pascal

Bardziej szczegółowo

Podstawowe operacje arytmetyczne i logiczne dla liczb binarnych

Podstawowe operacje arytmetyczne i logiczne dla liczb binarnych 1 Podstawowe operacje arytmetyczne i logiczne dla liczb binarnych 1. Podstawowe operacje logiczne dla cyfr binarnych Jeśli cyfry 0 i 1 potraktujemy tak, jak wartości logiczne fałsz i prawda, to działanie

Bardziej szczegółowo

Programowanie obiektowe. Wprowadzenie

Programowanie obiektowe. Wprowadzenie 1 Programowanie obiektowe Wprowadzenie 2 Programowanie obiektowe Object-oriented programming Najpopularniejszy obecnie styl (paradygmat) programowania Rozwinięcie koncepcji programowania strukturalnego

Bardziej szczegółowo

Pierwsze kroki. Algorytmy, niektóre zasady programowania, kompilacja, pierwszy program i jego struktura

Pierwsze kroki. Algorytmy, niektóre zasady programowania, kompilacja, pierwszy program i jego struktura Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.com Pierwsze kroki Algorytmy, niektóre zasady programowania, kompilacja, pierwszy program i jego struktura Co znaczy

Bardziej szczegółowo

1. Wprowadzanie danych z klawiatury funkcja scanf

1. Wprowadzanie danych z klawiatury funkcja scanf 1. Wprowadzanie danych z klawiatury funkcja scanf Deklaracja int scanf ( const char *format, wskaźnik, wskaźnik,... ) ; Biblioteka Działanie stdio.h Funkcja scanf wczytuje kolejne pola (ciągi znaków),

Bardziej szczegółowo

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna Język JAVA podstawy Wykład 3, część 3 1 Język JAVA podstawy Plan wykładu: 1. Konstrukcja kodu programów w Javie 2. Identyfikatory, zmienne 3. Typy danych 4. Operatory, instrukcje sterujące instrukcja warunkowe,

Bardziej szczegółowo

JAVAScript w dokumentach HTML (1)

JAVAScript w dokumentach HTML (1) JAVAScript w dokumentach HTML (1) JavaScript jest to interpretowany, zorientowany obiektowo, skryptowy język programowania. Skrypty JavaScript mogą być zagnieżdżane w dokumentach HTML. Instrukcje JavaScript

Bardziej szczegółowo

Klasy abstrakcyjne i interfejsy

Klasy abstrakcyjne i interfejsy Klasy abstrakcyjne i interfejsy Streszczenie Celem wykładu jest omówienie klas abstrakcyjnych i interfejsów w Javie. Czas wykładu 45 minut. Rozwiązanie w miarę standardowego zadania matematycznego (i nie

Bardziej szczegółowo

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje. Podstawowe elementy proceduralne w C++ Program i wyjście Zmienne i arytmetyka Wskaźniki i tablice Testy i pętle Funkcje Pierwszy program // Niezbędne zaklęcia przygotowawcze ;-) #include using

Bardziej szczegółowo

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut. Wyjątki Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut. Wydaje się, że żaden użytkownik oprogramowania nie lubi, kiedy stosowany program nagle zawiesza się,

Bardziej szczegółowo

Polimorfizm, metody wirtualne i klasy abstrakcyjne

Polimorfizm, metody wirtualne i klasy abstrakcyjne Programowanie obiektowe Polimorfizm, metody wirtualne i klasy abstrakcyjne Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej pawel.rogalinski pwr.wroc.pl Polimorfizm,

Bardziej szczegółowo

Arytmetyka komputera. Na podstawie podręcznika Urządzenia techniki komputerowej Tomasza Marciniuka. Opracował: Kamil Kowalski klasa III TI

Arytmetyka komputera. Na podstawie podręcznika Urządzenia techniki komputerowej Tomasza Marciniuka. Opracował: Kamil Kowalski klasa III TI Arytmetyka komputera Na podstawie podręcznika Urządzenia techniki komputerowej Tomasza Marciniuka Opracował: Kamil Kowalski klasa III TI Spis treści 1. Jednostki informacyjne 2. Systemy liczbowe 2.1. System

Bardziej szczegółowo

Aplikacje Internetowe. Najprostsza aplikacja. Komponenty Javy. Podstawy języka Java

Aplikacje Internetowe. Najprostsza aplikacja. Komponenty Javy. Podstawy języka Java Aplikacje Internetowe Podstawy języka Java Najprostsza aplikacja class Hello { public static void main(string[] args) { System.out.println("Hello World!"); Komponenty Javy JRE Java Runtime Environment

Bardziej szczegółowo

Pakiety i interfejsy. Tomasz Borzyszkowski

Pakiety i interfejsy. Tomasz Borzyszkowski Pakiety i interfejsy Tomasz Borzyszkowski Pakiety podstawy W dotychczasowych przykładach nazwy klas musiały pochodzić z jednej przestrzeni nazw, tj. być niepowtarzalne tak, by nie doprowadzić do kolizji

Bardziej szczegółowo

Wywoływanie metod zdalnych

Wywoływanie metod zdalnych Wywoływanie metod zdalnych model systemu Wywoływanie metod zdalnych aplikacja kliencka interfejs obiekt serwer Podejście obiektowe do budowy systemów rozproszonych proxy szkielet sieć Istota podejścia

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Laboratorium z przedmiotu Programowanie obiektowe - zestaw 02 Cel zajęć. Celem zajęć jest zapoznanie z praktycznymi aspektami projektowania oraz implementacji klas i obiektów z wykorzystaniem dziedziczenia.

Bardziej szczegółowo

10. Programowanie obiektowe w PHP5

10. Programowanie obiektowe w PHP5 Ogólnie definicja klasy wygląda jak w C++. Oczywiście elementy składowe klasy są zmiennymi PHP, stąd nieśmiertelne $. Warto zauważyć, że mogą one mieć wartość HHH mgr inż. Grzegorz Kraszewski TECHNOLOGIE

Bardziej szczegółowo

Zadanie 04 Ktory z ponizszych typow danych w jezyku ANSI C jest typem zmiennoprzecinkowym pojedynczej precyzji?

Zadanie 04 Ktory z ponizszych typow danych w jezyku ANSI C jest typem zmiennoprzecinkowym pojedynczej precyzji? Zadanie 01 W przedstawionym ponizej programie w jezyku ANSI C w miejscu wykropkowanym brakuje jednej linii: #include... int main() { printf("tralalalala"); return 0; } A. B. "iostream" C.

Bardziej szczegółowo

Ćwiczenie 1. Przygotowanie środowiska JAVA

Ćwiczenie 1. Przygotowanie środowiska JAVA Ćwiczenie 1 Przygotowanie środowiska JAVA 1. Wprowadzenie teoretyczne Instalacja JDK (Java Development Kit) NaleŜy pobrać z java.sun.com środowisko i zainstalować je. Następnie naleŝy skonfigurować środowisko.

Bardziej szczegółowo

Java: otwórz okienko. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Java: otwórz okienko. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak Java: otwórz okienko Programowanie w językach wysokiego poziomu mgr inż. Anna Wawszczak PLAN WYKŁADU klasy wewnętrzne, lokalne i anonimowe biblioteka AWT zestaw Swing JFrame JPanel komponenty obsługa zdarzeń

Bardziej szczegółowo

I - Microsoft Visual Studio C++

I - Microsoft Visual Studio C++ I - Microsoft Visual Studio C++ 1. Nowy projekt z Menu wybieramy File -> New -> Projekt -> Win32 Console Application w okienku Name: podajemy nazwę projektu w polu Location: wybieramy miejsce zapisu i

Bardziej szczegółowo

Komputer nie myśli. On tylko wykonuje nasze polecenia. Nauczmy się więc wydawać mu rozkazy

Komputer nie myśli. On tylko wykonuje nasze polecenia. Nauczmy się więc wydawać mu rozkazy Programowanie w C++ 1.Czym jest programowanie Pisanie programów to wcale nie czarna magia, tylko bardzo logiczna rozmowa z komputerem. Oczywiście w jednym ze specjalnie stworzonych do tego celu języków.

Bardziej szczegółowo

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1 Współbieżność i równoległość w środowiskach obiektowych Krzysztof Banaś Obliczenia równoległe 1 Java Model współbieżności Javy opiera się na realizacji szeregu omawianych dotychczas elementów: zarządzanie

Bardziej szczegółowo

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody Obiektowy PHP Czym jest obiekt? W programowaniu obiektem można nazwać każdy abstrakcyjny byt, który programista utworzy w pamięci komputera. Jeszcze bardziej upraszczając to zagadnienie, można powiedzieć,

Bardziej szczegółowo

ARYTMETYKA BINARNA. Dziesiątkowy system pozycyjny nie jest jedynym sposobem kodowania liczb z jakim mamy na co dzień do czynienia.

ARYTMETYKA BINARNA. Dziesiątkowy system pozycyjny nie jest jedynym sposobem kodowania liczb z jakim mamy na co dzień do czynienia. ARYTMETYKA BINARNA ROZWINIĘCIE DWÓJKOWE Jednym z najlepiej znanych sposobów kodowania informacji zawartej w liczbach jest kodowanie w dziesiątkowym systemie pozycyjnym, w którym dla przedstawienia liczb

Bardziej szczegółowo

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016 Wykład 2 17 marca 2016 Dziedziczenie Klasy bazowe i potomne Dziedziczenie jest łatwym sposobem rozwijania oprogramowania. Majac klasę bazowa możemy ja uszczegółowić (dodać nowe pola i metody) nie przepisujac

Bardziej szczegółowo

Python wstęp do programowania dla użytkowników WCSS

Python wstęp do programowania dla użytkowników WCSS Python wstęp do programowania dla użytkowników WCSS Dr inż. Krzysztof Berezowski Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej Wprowadzenie CHARAKTERYSTYKA JĘZYKA Filozofia języka

Bardziej szczegółowo

Język JAVA podstawy. wykład 1, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Język JAVA podstawy. wykład 1, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna Język JAVA podstawy wykład 1, część 3 1 Język JAVA podstawy Plan wykładu: 1. Krótka historia Javy 2. Jak przygotować sobie środowisko programistyczne 3. Opis środowiska JDK 4. Tworzenie programu krok po

Bardziej szczegółowo

Metody Metody, parametry, zwracanie wartości

Metody Metody, parametry, zwracanie wartości Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.com Metody Metody, parametry, zwracanie wartości Metody - co to jest i po co? Metoda to wydzielona część klasy, mająca

Bardziej szczegółowo

Algorytmika i Programowanie VBA 1 - podstawy

Algorytmika i Programowanie VBA 1 - podstawy Algorytmika i Programowanie VBA 1 - podstawy Tomasz Sokół ZZI, IL, PW Czas START uruchamianie środowiska VBA w Excelu Alt-F11 lub Narzędzia / Makra / Edytor Visual Basic konfiguracja środowiska VBA przy

Bardziej szczegółowo

Elżbieta Kula - wprowadzenie do Turbo Pascala i algorytmiki

Elżbieta Kula - wprowadzenie do Turbo Pascala i algorytmiki Elżbieta Kula - wprowadzenie do Turbo Pascala i algorytmiki Turbo Pascal jest językiem wysokiego poziomu, czyli nie jest rozumiany bezpośrednio dla komputera, ale jednocześnie jest wygodny dla programisty,

Bardziej szczegółowo

Kurs WWW. Paweł Rajba. pawel@ii.uni.wroc.pl http://pawel.ii.uni.wroc.pl/

Kurs WWW. Paweł Rajba. pawel@ii.uni.wroc.pl http://pawel.ii.uni.wroc.pl/ Paweł Rajba pawel@ii.uni.wroc.pl http://pawel.ii.uni.wroc.pl/ Spis treści Wprowadzenie Automatyczne ładowanie klas Składowe klasy, widoczność składowych Konstruktory i tworzenie obiektów Destruktory i

Bardziej szczegółowo

Cw.12 JAVAScript w dokumentach HTML

Cw.12 JAVAScript w dokumentach HTML Cw.12 JAVAScript w dokumentach HTML Wstawienie skryptu do dokumentu HTML JavaScript jest to interpretowany, zorientowany obiektowo, skryptowy język programowania.skrypty Java- Script mogą być zagnieżdżane

Bardziej szczegółowo

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1 Obiektowe programowanie rozproszone Java RMI Krzysztof Banaś Systemy rozproszone 1 Java RMI Mechanizm zdalnego wywołania metod Javy (RMI Remote Method Invocation) posiada kilka charakterystycznych cech,

Bardziej szczegółowo

Programowanie, algorytmy i struktury danych

Programowanie, algorytmy i struktury danych 1/44 Programowanie, algorytmy i struktury danych materiały do wykładu: http://cez.wipb.pl/moodle/ email: m.tabedzki@pb.edu.pl strona: http://aragorn.pb.bialystok.pl/~tabedzki/ Marek Tabędzki Wymagania

Bardziej szczegółowo

Wątek - definicja. Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego

Wątek - definicja. Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego Wątki Wątek - definicja Ciąg instrukcji (podprogram) który może być wykonywane współbieżnie (równolegle) z innymi programami, Wątki działają w ramach tego samego procesu Współdzielą dane (mogą operować

Bardziej szczegółowo

Rys.2.1. Trzy warstwy stanowiące podstawę popularnego podejścia w zakresie budowy stron internetowych [2]

Rys.2.1. Trzy warstwy stanowiące podstawę popularnego podejścia w zakresie budowy stron internetowych [2] 1. CEL ĆWICZENIA Celem ćwiczenia jest przedstawienie możliwości wykorzystania języka JavaScript do tworzenia interaktywnych aplikacji działających po stronie klienta. 2. MATERIAŁ NAUCZANIA JavaScript tak

Bardziej szczegółowo

Programowanie wieloplatformowe w Java

Programowanie wieloplatformowe w Java Programowanie wieloplatformowe w Java dr Krzysztof Podlaski 1 Kwestie organizacyjne Wykład: 15 godzin Zaliczenie test Ćwiczenia 30 godzin (dr K.Podlaski) Zaliczenie projekt Konsultacje: do ustalenia, Kontakt:

Bardziej szczegółowo

Informatyka- wykład. Podstawy programowania w Pythonie. dr Marcin Ziółkowski

Informatyka- wykład. Podstawy programowania w Pythonie. dr Marcin Ziółkowski Informatyka- wykład Podstawy programowania w Pythonie dr Marcin Ziółkowski Instytut Matematyki i Informatyki Akademia im. Jana Długosza w Częstochowie 23 listopada 2015 r. JĘZYK PYTHON Język Python jest

Bardziej szczegółowo

TOPIT Załącznik nr 3 Programowanie aplikacji internetowych

TOPIT Załącznik nr 3 Programowanie aplikacji internetowych Szkolenie przeznaczone jest dla osób chcących poszerzyć swoje umiejętności o tworzenie rozwiązań internetowych w PHP. Zajęcia zostały przygotowane w taki sposób, aby po ich ukończeniu można było rozpocząć

Bardziej szczegółowo

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre) Uwagi dotyczące notacji kodu! Wyrazy drukiem prostym -- słowami języka VBA. Wyrazy drukiem pochyłym -- inne fragmenty kodu. Wyrazy w [nawiasach kwadratowych] opcjonalne fragmenty kodu (mogą być, ale nie

Bardziej szczegółowo

Właściwości i metody obiektu Comment Właściwości

Właściwości i metody obiektu Comment Właściwości Właściwości i metody obiektu Comment Właściwości Właściwość Czy można zmieniać Opis Application nie Zwraca nazwę aplikacji, która utworzyła komentarz Author nie Zwraca nazwę osoby, która utworzyła komentarz

Bardziej szczegółowo

Podstawy programowania - 1

Podstawy programowania - 1 Podstawy programowania - 1 doc. dr inż. Tadeusz Jeleniewski Wykład: sobota B, godz. 10.30 12.55 sala 12 Laboratorium: sobota B, godz. 13.00 15.25 sala 2 sobota B, godz. 15.30-17.55 sala 2 e-mail: tadeusz.jeleniewski@pwr.wroc.pl

Bardziej szczegółowo

Programowanie RAD Delphi

Programowanie RAD Delphi Programowanie RAD Delphi Dr Sławomir Orłowski Zespół Fizyki Medycznej, Instytut Fizyki, Uniwersytet Mikołaja Kopernika w Toruniu Pokój: 202, tel. 611-32-46, e-mial: bigman@fizyka.umk.pl Delphi zasoby Aplikacje

Bardziej szczegółowo

Szablony funkcji i szablony klas

Szablony funkcji i szablony klas Bogdan Kreczmer bogdan.kreczmer@pwr.wroc.pl Zakład Podstaw Cybernetyki i Robotyki Instytut Informatyki, Automatyki i Robotyki Politechnika Wrocławska Kurs: Copyright c 2011 Bogdan Kreczmer Niniejszy dokument

Bardziej szczegółowo

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami. UML a kod w C++ i Javie Projektowanie oprogramowania Dokumentowanie oprogramowania Diagramy przypadków użycia Przewoznik Zarzadzanie pojazdami Optymalizacja Uzytkownik Wydawanie opinii Zarzadzanie uzytkownikami

Bardziej szczegółowo

Należy ściągnąć oprogramowanie Apache na platformę

Należy ściągnąć oprogramowanie Apache na platformę Programowanie Internetowe Język PHP - wprowadzenie 1. Instalacja Oracle+Apache+PHP Instalacja Apache, PHP, Oracle Programy i ich lokalizacja Oracle Database 10g Express Edition10.2 http://www.oracle.com/technology/products/database/

Bardziej szczegółowo

Wykład V. Rzut okiem na języki programowania. Studia Podyplomowe INFORMATYKA Podstawy Informatyki

Wykład V. Rzut okiem na języki programowania. Studia Podyplomowe INFORMATYKA Podstawy Informatyki Studia Podyplomowe INFORMATYKA Podstawy Informatyki Wykład V Rzut okiem na języki programowania 1 Kompilacja vs. interpretacja KOMPILACJA Proces, który przetwarza program zapisany w języku programowania,

Bardziej szczegółowo

Kompilator języka C na procesor 8051 RC51 implementacja

Kompilator języka C na procesor 8051 RC51 implementacja Kompilator języka C na procesor 8051 RC51 implementacja Implementowane typy danych bit 1 bit char lub char signed 8 bitów char unsigned 8 bitów int lub signed int 16 bitów unsigned int 16 bitów long lub

Bardziej szczegółowo

Język skryptowy: Laboratorium 1. Wprowadzenie do języka Python

Język skryptowy: Laboratorium 1. Wprowadzenie do języka Python Język skryptowy: Laboratorium 1. Wprowadzenie do języka Python Język PYTHON Podstawowe informacje Python to język skryptowy, interpretowany - co oznacza, że piszemy skrypt, a następnie wykonujemy go za

Bardziej szczegółowo

Podstawy programowania C. dr. Krystyna Łapin http://www.mif.vu.lt/~moroz/c/

Podstawy programowania C. dr. Krystyna Łapin http://www.mif.vu.lt/~moroz/c/ Podstawy programowania C dr. Krystyna Łapin http://www.mif.vu.lt/~moroz/c/ Tematy Struktura programu w C Typy danych Operacje Instrukcja grupująca Instrukcja przypisania Instrukcja warunkowa Struktura

Bardziej szczegółowo

Programowanie I. O czym będziemy mówili. Plan wykładu nieco dokładniej. Plan wykładu z lotu ptaka. Podstawy programowania w językach. Uwaga!

Programowanie I. O czym będziemy mówili. Plan wykładu nieco dokładniej. Plan wykładu z lotu ptaka. Podstawy programowania w językach. Uwaga! Programowanie I O czym będziemy mówili Podstawy programowania w językach proceduralnym ANSI C obiektowym Java Uwaga! podobieństwa w podstawowej strukturze składniowej (zmienne, operatory, instrukcje sterujące...)

Bardziej szczegółowo

Paradygmaty programowania

Paradygmaty programowania Paradygmaty programowania Jacek Michałowski, Piotr Latanowicz 15 kwietnia 2014 Jacek Michałowski, Piotr Latanowicz () Paradygmaty programowania 15 kwietnia 2014 1 / 12 Zadanie 1 Zadanie 1 Rachunek predykatów

Bardziej szczegółowo

JAVAScript w dokumentach HTML (1) JavaScript jest to interpretowany, zorientowany obiektowo, skryptowy język programowania.

JAVAScript w dokumentach HTML (1) JavaScript jest to interpretowany, zorientowany obiektowo, skryptowy język programowania. IŚ ćw.8 JAVAScript w dokumentach HTML (1) JavaScript jest to interpretowany, zorientowany obiektowo, skryptowy język programowania. Skrypty JavaScript są zagnieżdżane w dokumentach HTML. Skrypt JavaScript

Bardziej szczegółowo